1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | function lockfile(prop, opts = {}) {
|
4 | const Lockfile = require('./lockfile').default;
|
5 | return methodDecorator(function ({ original, propertyName }) {
|
6 | return function (...args) {
|
7 | const lockfile = this[prop];
|
8 | if (!(lockfile instanceof Lockfile)) {
|
9 | throw new Error('prop does not point to a Lockfile instance');
|
10 | }
|
11 | if (opts.sync) {
|
12 | lockfile.addSync({ reason: propertyName.toString() });
|
13 | try {
|
14 | return original.apply(this, args);
|
15 | }
|
16 | finally {
|
17 | lockfile.removeSync();
|
18 | }
|
19 | }
|
20 | else {
|
21 | return (async () => {
|
22 | await lockfile.add({ reason: propertyName.toString() });
|
23 | try {
|
24 | return await original.apply(this, args);
|
25 | }
|
26 | finally {
|
27 | await lockfile.remove();
|
28 | }
|
29 | })();
|
30 | }
|
31 | };
|
32 | });
|
33 | }
|
34 | exports.lockfile = lockfile;
|
35 | function rwlockfile(prop, type, opts = {}) {
|
36 | const RWLockfile = require('./rwlockfile').default;
|
37 | return methodDecorator(function ({ original, propertyName }) {
|
38 | return async function (...args) {
|
39 | const lockfile = this[prop];
|
40 | if (!(lockfile instanceof RWLockfile)) {
|
41 | throw new Error('prop does not point to a Lockfile instance');
|
42 | }
|
43 | const addOpts = {
|
44 | reason: propertyName.toString(),
|
45 | };
|
46 | if (opts.ifLocked) {
|
47 | addOpts.ifLocked = () => this[opts.ifLocked]();
|
48 | }
|
49 | await lockfile.add(type, addOpts);
|
50 | let result;
|
51 | try {
|
52 | result = await original.apply(this, args);
|
53 | }
|
54 | finally {
|
55 | await lockfile.remove(type);
|
56 | }
|
57 | return result;
|
58 | };
|
59 | });
|
60 | }
|
61 | exports.rwlockfile = rwlockfile;
|
62 | function onceAtATime(argKey) {
|
63 | return methodDecorator(function ({ original }) {
|
64 | const key = Symbol('onceAtATime');
|
65 | return async function (...args) {
|
66 | const subKey = argKey !== undefined ? args[argKey] : key;
|
67 | const cache = (this[key] = this[key] || {});
|
68 | if (cache[subKey])
|
69 | return cache[subKey];
|
70 | cache[subKey] = original.apply(this, args);
|
71 | try {
|
72 | return await cache[subKey];
|
73 | }
|
74 | finally {
|
75 | delete cache[subKey];
|
76 | }
|
77 | };
|
78 | });
|
79 | }
|
80 | exports.onceAtATime = onceAtATime;
|
81 | function methodDecorator(fn) {
|
82 | return (target, propertyName, descriptor) => {
|
83 | if (isMethodDecorator(descriptor)) {
|
84 | descriptor.value = fn({ target, propertyName, descriptor, original: descriptor.value });
|
85 | return descriptor;
|
86 | }
|
87 | else {
|
88 | throw new Error(`${propertyName} on ${target} is not a a method`);
|
89 | }
|
90 | };
|
91 | }
|
92 | function isMethodDecorator(prop) {
|
93 | if (!prop)
|
94 | return false;
|
95 | return !!prop.value;
|
96 | }
|