@lowerdeck/lock 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,12 +1,13 @@
1
1
 
2
2
  $ microbundle
3
+ No name was provided for external module '@lowerdeck/delay' in output.globals – guessing 'delay'
3
4
  No name was provided for external module '@lowerdeck/redis' in output.globals – guessing 'redis'
4
5
  Build "@lowerdeck/lock" to dist:
5
- 1418 B: index.cjs.gz
6
- 1275 B: index.cjs.br
7
- 654 B: index.module.js.gz
8
- 592 B: index.module.js.br
9
- 1390 B: index.module.js.gz
10
- 1263 B: index.module.js.br
6
+ 1425 B: index.cjs.gz
7
+ 1286 B: index.cjs.br
8
+ 635 B: index.module.js.gz
9
+ 593 B: index.module.js.br
10
+ 1382 B: index.module.js.gz
11
+ 1259 B: index.module.js.br
11
12
  1509 B: index.umd.js.gz
12
- 1371 B: index.umd.js.br
13
+ 1377 B: index.umd.js.br
package/CHANGELOG.md ADDED
@@ -0,0 +1,19 @@
1
+ # @lowerdeck/lock
2
+
3
+ ## 1.0.2
4
+
5
+ ### Patch Changes
6
+
7
+ - Fix default entry point
8
+ - Updated dependencies
9
+ - @lowerdeck/delay@1.0.3
10
+ - @lowerdeck/redis@1.0.2
11
+
12
+ ## 1.0.1
13
+
14
+ ### Patch Changes
15
+
16
+ - update versions
17
+ - Updated dependencies
18
+ - @lowerdeck/delay@1.0.2
19
+ - @lowerdeck/redis@1.0.1
package/dist/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- var n=require("@lowerdeck/redis"),e=require("ioredis"),r=require("superjson"),t=require("redlock");function i(n){return n&&"object"==typeof n&&"default"in n?n:{default:n}}var u=/*#__PURE__*/i(r),o=/*#__PURE__*/i(t),c=function(n){return new Promise(function(e){return setTimeout(e,n)})};function f(n,e,r){if(!n.s){if(r instanceof s){if(!r.s)return void(r.o=f.bind(null,n,e));1&e&&(e=r.s),r=r.v}if(r&&r.then)return void r.then(f.bind(null,n,e),f.bind(null,n,2));n.s=e,n.v=r;const t=n.o;t&&t(n)}}var s=/*#__PURE__*/function(){function n(){}return n.prototype.then=function(e,r){var t=new n,i=this.s;if(i){var u=1&i?e:r;if(u){try{f(t,1,u(this.v))}catch(n){f(t,2,n)}return t}return this}return this.o=function(n){try{var i=n.v;1&n.s?f(t,1,e?e(i):i):r?f(t,1,r(i)):f(t,2,i)}catch(n){f(t,2,n)}},t},n}();function h(n){return n instanceof s&&1&n.s}exports.createLock=function(r){var t=r.redisUrl,i=Bun.hash.cityHash32(r.name),a=new e.Redis(n.parseRedisUrl(t)),v=new o.default([a],{driftFactor:.01,retryCount:50,retryDelay:200,retryJitter:200,automaticExtensionThreshold:500}),l=function(n,e){try{var r=(Array.isArray(n)?n:[n]).map(function(n){return"l:"+i+":"+n}),t=function(){try{var n=!1,i=function(){n=!0};return Promise.resolve(v.using(r,1e4,function(){return e({passForNow:i})})).then(function(e){var r,i=function(){if(n)return Promise.resolve(c(100)).then(function(){var n=t();return r=1,n})}();return i&&i.then?i.then(function(n){return r?n:e}):r?i:e})}catch(n){return Promise.reject(n)}};return t()}catch(n){return Promise.reject(n)}},d=function(n,e){try{var r=i+":"+Math.random()+":"+Date.now(),t="luniq:"+i+":"+n;return Promise.resolve(a.setnx(t,r)).then(function(i){return Promise.resolve(a.expire(t,300)).then(function(){var u;function o(n){return u?n:Promise.resolve(a.get(t)).then(function(n){var e;if(!n)return null;var r=0,t=function(n,e,r){for(var t;;){var i=n();if(h(i)&&(i=i.v),!i)return u;if(i.then){t=0;break}var u=r();if(u&&u.then){if(!h(u)){t=1;break}u=u.s}if(e){var o=e();if(o&&o.then&&!h(o)){t=2;break}}}var c=new s,a=f.bind(null,c,2);return(0===t?i.then(l):1===t?u.then(v):o.then(d)).then(void 0,a),c;function v(t){u=t;do{if(e&&(o=e())&&o.then&&!h(o))return void o.then(d).then(void 0,a);if(!(i=n())||h(i)&&!i.v)return void f(c,1,u);if(i.then)return void i.then(l).then(void 0,a);h(u=r())&&(u=u.v)}while(!u||!u.then);u.then(v).then(void 0,a)}function l(n){n?(u=r())&&u.then?u.then(v).then(void 0,a):v(u):f(c,1,u)}function d(){(i=n())?i.then?i.then(l).then(void 0,a):l(i):f(c,1,u)}}(function(){return!e&&r<25},function(){return r++},function(){function t(){return Promise.resolve(a.get("luniq:"+n+":done")).then(function(n){if(n)return e=1,null})}var i=function(){if(r>0)return Promise.resolve(c(25)).then(function(){})}();return i&&i.then?i.then(t):t()});return t&&t.then?t.then(function(n){return e?n:null}):e?t:null})}var v=function(){if(i)return Promise.resolve(l(n,function(){try{return Promise.resolve(function(n,e){try{var r=n()}catch(n){return e(!0,n)}return r&&r.then?r.then(e.bind(null,!1),e.bind(null,!0)):e(!1,r)}(e,function(n,e){return Promise.resolve(a.set("luniq:"+r+":done","1","EX",10)).then(function(){return Promise.resolve(a.expire(t,5)).then(function(){if(n)throw e;return e})})}))}catch(n){return Promise.reject(n)}})).then(function(n){return u=1,n})}();return v&&v.then?v.then(o):o(v)})})}catch(n){return Promise.reject(n)}};return{usingLock:l,doOnce:d,doOnceAndReturn:function(n,e){var r="doa:"+i+":"+n;return Promise.resolve(d(n,function(){try{return Promise.resolve(e()).then(function(n){return Promise.resolve(a.set(r,u.default.stringify(n),"EX",60)).then(function(){return n})})}catch(n){return Promise.reject(n)}})).then(function(n){var e,t=function(){if(null==n){var t=u.default.parse;return Promise.resolve(a.get(r)).then(function(n){var r=t.call(u.default,n);return e=1,r})}}();return t&&t.then?t.then(function(r){return e?r:n}):e?t:n})}}};
1
+ var n=require("@lowerdeck/delay"),e=require("@lowerdeck/redis"),r=require("ioredis"),t=require("superjson"),i=require("redlock");function u(n){return n&&"object"==typeof n&&"default"in n?n:{default:n}}var o=/*#__PURE__*/u(t),c=/*#__PURE__*/u(i);function f(n,e,r){if(!n.s){if(r instanceof s){if(!r.s)return void(r.o=f.bind(null,n,e));1&e&&(e=r.s),r=r.v}if(r&&r.then)return void r.then(f.bind(null,n,e),f.bind(null,n,2));n.s=e,n.v=r;const t=n.o;t&&t(n)}}var s=/*#__PURE__*/function(){function n(){}return n.prototype.then=function(e,r){var t=new n,i=this.s;if(i){var u=1&i?e:r;if(u){try{f(t,1,u(this.v))}catch(n){f(t,2,n)}return t}return this}return this.o=function(n){try{var i=n.v;1&n.s?f(t,1,e?e(i):i):r?f(t,1,r(i)):f(t,2,i)}catch(n){f(t,2,n)}},t},n}();function h(n){return n instanceof s&&1&n.s}exports.createLock=function(t){var i=t.redisUrl,u=Bun.hash.cityHash32(t.name),a=new r.Redis(e.parseRedisUrl(i)),l=new c.default([a],{driftFactor:.01,retryCount:50,retryDelay:200,retryJitter:200,automaticExtensionThreshold:500}),v=function(e,r){try{var t=(Array.isArray(e)?e:[e]).map(function(n){return"l:"+u+":"+n}),i=function(){try{var e=!1,u=function(){e=!0};return Promise.resolve(l.using(t,1e4,function(){return r({passForNow:u})})).then(function(r){var t,u=function(){if(e)return Promise.resolve(n.delay(100)).then(function(){var n=i();return t=1,n})}();return u&&u.then?u.then(function(n){return t?n:r}):t?u:r})}catch(n){return Promise.reject(n)}};return i()}catch(n){return Promise.reject(n)}},d=function(e,r){try{var t=u+":"+Math.random()+":"+Date.now(),i="luniq:"+u+":"+e;return Promise.resolve(a.setnx(i,t)).then(function(u){return Promise.resolve(a.expire(i,300)).then(function(){var o;function c(e){return o?e:Promise.resolve(a.get(i)).then(function(e){var r;if(!e)return null;var t=0,i=function(n,e,r){for(var t;;){var i=n();if(h(i)&&(i=i.v),!i)return u;if(i.then){t=0;break}var u=r();if(u&&u.then){if(!h(u)){t=1;break}u=u.s}if(e){var o=e();if(o&&o.then&&!h(o)){t=2;break}}}var c=new s,a=f.bind(null,c,2);return(0===t?i.then(v):1===t?u.then(l):o.then(d)).then(void 0,a),c;function l(t){u=t;do{if(e&&(o=e())&&o.then&&!h(o))return void o.then(d).then(void 0,a);if(!(i=n())||h(i)&&!i.v)return void f(c,1,u);if(i.then)return void i.then(v).then(void 0,a);h(u=r())&&(u=u.v)}while(!u||!u.then);u.then(l).then(void 0,a)}function v(n){n?(u=r())&&u.then?u.then(l).then(void 0,a):l(u):f(c,1,u)}function d(){(i=n())?i.then?i.then(v).then(void 0,a):v(i):f(c,1,u)}}(function(){return!r&&t<25},function(){return t++},function(){function i(){return Promise.resolve(a.get("luniq:"+e+":done")).then(function(n){if(n)return r=1,null})}var u=function(){if(t>0)return Promise.resolve(n.delay(25)).then(function(){})}();return u&&u.then?u.then(i):i()});return i&&i.then?i.then(function(n){return r?n:null}):r?i:null})}var l=function(){if(u)return Promise.resolve(v(e,function(){try{return Promise.resolve(function(n,e){try{var r=n()}catch(n){return e(!0,n)}return r&&r.then?r.then(e.bind(null,!1),e.bind(null,!0)):e(!1,r)}(r,function(n,e){return Promise.resolve(a.set("luniq:"+t+":done","1","EX",10)).then(function(){return Promise.resolve(a.expire(i,5)).then(function(){if(n)throw e;return e})})}))}catch(n){return Promise.reject(n)}})).then(function(n){return o=1,n})}();return l&&l.then?l.then(c):c(l)})})}catch(n){return Promise.reject(n)}};return{usingLock:v,doOnce:d,doOnceAndReturn:function(n,e){var r="doa:"+u+":"+n;return Promise.resolve(d(n,function(){try{return Promise.resolve(e()).then(function(n){return Promise.resolve(a.set(r,o.default.stringify(n),"EX",60)).then(function(){return n})})}catch(n){return Promise.reject(n)}})).then(function(n){var e,t=function(){if(null==n){var t=o.default.parse;return Promise.resolve(a.get(r)).then(function(n){var r=t.call(o.default,n);return e=1,r})}}();return t&&t.then?t.then(function(r){return e?r:n}):e?t:n})}}};
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../../delay/dist/index.module.js","../src/index.ts"],"sourcesContent":["var e=function(e){return new Promise(function(n){return setTimeout(n,e)})};export{e as delay};\n//# sourceMappingURL=index.module.js.map\n","import { delay } from '@lowerdeck/delay';\nimport { parseRedisUrl } from '@lowerdeck/redis';\nimport { Redis } from 'ioredis';\n\n// @ts-ignore\nimport SuperJSON from 'superjson';\n\n// @ts-ignore\nimport Redlock_ from 'redlock';\n\nexport let createLock = ({ name, redisUrl }: { name: string; redisUrl: string }) => {\n let nameHash = Bun.hash.cityHash32(name);\n let redis = new Redis(parseRedisUrl(redisUrl));\n\n let redlock = new Redlock_([redis as any], {\n // The expected clock drift; for more details see:\n // http://redis.io/topics/distlock\n driftFactor: 0.01, // multiplied by lock ttl to determine drift time\n\n // The max number of times Redlock will attempt to lock a resource\n // before erroring.\n retryCount: 50,\n\n // the time in ms between attempts\n retryDelay: 200, // time in ms\n\n // the max time in ms randomly added to retries\n // to improve performance under high contention\n // see https://www.awsarchitectureblog.com/2015/03/backoff.html\n retryJitter: 200, // time in ms\n\n // The minimum remaining time on a lock before an extension is automatically\n // attempted with the `using` API.\n automaticExtensionThreshold: 500\n } as any);\n\n let usingLock = async <T>(\n key: string | string[],\n fn: (controller: { passForNow: () => void }) => Promise<T>\n ): Promise<T> => {\n let keyArray = (Array.isArray(key) ? key : [key]).map(k => `l:${nameHash}:${k}`);\n\n let runLock = async () => {\n let passingForNow = false;\n let passForNow = () => {\n passingForNow = true;\n };\n\n let result = await redlock.using(keyArray, 10_000, () => fn({ passForNow }));\n\n if (passingForNow) {\n await delay(100);\n return runLock();\n }\n\n return result;\n };\n\n return runLock();\n };\n\n let doOnce = async <T>(key: string, fn: () => Promise<T>): Promise<T | null> => {\n let id = `${nameHash}:${Math.random()}:${Date.now()}`;\n let uniquenessHashKey = `luniq:${nameHash}:${key}`;\n\n let keyWasSet = await redis.setnx(uniquenessHashKey, id);\n await redis.expire(uniquenessHashKey, 60 * 5);\n\n if (keyWasSet) {\n return await usingLock(key, async () => {\n try {\n return await fn();\n } finally {\n await redis.set(`luniq:${id}:done`, '1', 'EX', 10);\n await redis.expire(uniquenessHashKey, 5);\n }\n });\n }\n\n let winnerId = await redis.get(uniquenessHashKey);\n if (!winnerId) return null;\n\n // If we lost, we'll wait for the winner to finish.\n for (let i = 0; i < 25; i++) {\n if (i > 0) await delay(25);\n\n if (await redis.get(`luniq:${winnerId}:done`)) {\n return null;\n }\n }\n\n return null;\n };\n\n let doOnceAndReturn = async <T>(key: string, fn: () => Promise<T>): Promise<T> => {\n let redisKey = `doa:${nameHash}:${key}`;\n\n let res = await doOnce(key, async () => {\n let res = await fn();\n\n await redis.set(redisKey, SuperJSON.stringify(res), 'EX', 60);\n\n return res;\n });\n\n if (res == null) {\n return SuperJSON.parse((await redis.get(redisKey)) as string);\n }\n\n return res;\n };\n\n return {\n usingLock,\n doOnce,\n doOnceAndReturn\n };\n};\n"],"names":["e","Promise","n","setTimeout","_settle","state","value","pact","s","_Pact","o","v","then","bind","observer","prototype","onFulfilled","onRejected","result","this","callback","_this","_isSettledPact","thenable","_ref","redisUrl","nameHash","Bun","hash","cityHash32","name","redis","Redis","parseRedisUrl","redlock","Redlock_","driftFactor","retryCount","retryDelay","retryJitter","automaticExtensionThreshold","usingLock","key","fn","keyArray","Array","isArray","map","k","runLock","passingForNow","passForNow","resolve","using","_exit","_temp","delay","_runLock","_result","reject","doOnce","id","Math","random","Date","now","uniquenessHashKey","setnx","keyWasSet","expire","_exit2","_temp7","_result2","get","winnerId","_exit3","i","_temp5","_for","_temp4","_redis$get","_temp3","_result3","_temp6","_finallyRethrows","_wasThrown","_result4","set","_await$usingLock","doOnceAndReturn","redisKey","res","SuperJSON","stringify","_exit4","_temp8","_parse","parse","_redis$get2","_SuperJSON$parse","call","_result5"],"mappings":"uNAAWA,EAAQ,SAACA,GAAU,OAAS,IAAAC,QAAQ,SAAAC,GAAO,OAAIC,WAAWD,EAASF,EAAG,EAAC,ECuD5E,SAAAI,IAAcC,EAAAC,GAChB,IAAAC,EAAEC,EAAA,iBAEKC,EAAU,CACnB,IAAEH,EAAAE,EAUE,cADEE,EAAAN,OAAY,KAAAG,EAAAF,MAPdA,IACFA,EAAMC,EAAME,KAGRF,EAAAK,UAOCC,KACC,0BADS,KAAAL,EAAAF,GAAAD,EAAAS,KAAA,KAAAN,EAAA,UAIbA,EAAAI,EAAAL,QACFQ,EAACP,EAAAG,KAGDI,EAAIP,GAGJ,CAlFG,IAAEE,0BACT,SAAAA,IAAgB,QAEHA,EAAAM,UAAAH,KAAA,SAAAI,EAAAC,GACN,IAAAC,EAAe,IAAAT,EAETJ,EAAAc,KAAAX,EACN,GAAAH,EAAA,CAED,IAAKe,EAAgB,EAAhBf,EAAsBW,EAAkDC,KAC7EG,EAAW,CACf,IAEIhB,EAAAc,EAAc,EAAAE,EAAUD,KAAaR,UACWX,KAChBkB,EAAA,EAAAlB,UAGgCkB,EAElE,OAAAC,KAyBE,cApB6C,SAAAE,WAEgBf,EAAAe,EAAAV,EACpD,EAAXU,EAAWb,IAEiEU,EAAA,EAAAF,EAAAA,EAAAV,GAAAA,GAC1CW,EAClCb,EAAAc,EAAA,EAAAD,EAA2BX,IAGzBF,EAAAc,EAAiB,EAAAZ,EAMnB,CAAA,MAAIN,KACFkB,EAAI,EAAAlB,KAGJkB,IAKE,IAiCS,SAAAI,EAAeC,uBAEtBd,GAAiC,IAAAD,CACnC,oBA7EgB,SAAHgB,GAA8D,IAAlDC,EAAQD,EAARC,SAC3BC,EAAWC,IAAIC,KAAKC,WADKL,EAAJM,MAErBC,EAAQ,IAAIC,QAAMC,EAAAA,cAAcR,IAEhCS,EAAU,IAAIC,EAAQ,QAAC,CAACJ,GAAe,CAGzCK,YAAa,IAIbC,WAAY,GAGZC,WAAY,IAKZC,YAAa,IAIbC,4BAA6B,MAG3BC,EAAA,SACFC,EACAC,OAEA,IAAIC,GAAYC,MAAMC,QAAQJ,GAAOA,EAAM,CAACA,IAAMK,IAAI,SAAAC,GAAUtB,MAAAA,KAAAA,MAAYsB,CAAC,GAEzEC,EAAA,WAAO,IACT,IAAIC,GAAgB,EAChBC,EAAa,WACfD,GAAgB,CAClB,EAAE,OAAAjD,QAAAmD,QAEiBlB,EAAQmB,MAAMT,EAAU,IAAQ,WAAA,OAAMD,EAAG,CAAEQ,WAAAA,GAAa,IAACvC,KAAA,SAAxEM,GAAMoC,IAAAA,EAAAC,EAAA,WAAA,GAENL,EAAajD,OAAAA,QAAAmD,QACTI,EAAM,MAAI5C,KAAA,WAAA,IAAA6C,EACTR,WAASK,IAAAG,CAAA,EAAA,CAJR,GAIQ,OAAAF,GAAAA,EAAA3C,KAAA2C,EAAA3C,KAAA,SAAA8C,GAAAJ,OAAAA,EAAAI,EAGXxC,CAAM,GAAAoC,EAAAC,EAANrC,CAAM,EACf,CAAC,MAAAlB,GAAAC,OAAAA,QAAA0D,OAAA3D,EAAA,CAAA,EAED,OAAOiD,GACT,CAAC,MAAAjD,UAAAC,QAAA0D,OAAA3D,EAAA,CAAA,EAEG4D,WAAmBlB,EAAaC,GAAoB,IACtD,IAAIkB,EAAQnC,EAAYoC,IAAAA,KAAKC,SAAQ,IAAIC,KAAKC,MAC1CC,EAA6BxC,SAAAA,EAAYgB,IAAAA,EAAM,OAAAzC,QAAAmD,QAE7BrB,EAAMoC,MAAMD,EAAmBL,IAAGjD,KAApDwD,SAAAA,UAASnE,QAAAmD,QACPrB,EAAMsC,OAAOH,EAAmB,MAAOtD,oBAAA0D,EAAA,SAAAC,EAAAC,GAAAF,OAAAA,EAAAE,EAAAvE,QAAAmD,QAaxBrB,EAAM0C,IAAIP,IAAkBtD,KAAA,SAA7C8D,GAAQC,IAAAA,EACZ,IAAKD,EAAU,OAAO,KAGjB,IAAIE,EAAI,EAACC,4pBAAAC,CAAA,WAAA,OAAAH,GAAEC,EAAI,EAAE,oBAAEA,GAAG,EAAE,WAAA,SAAAG,IAAA,OAAA9E,QAAAmD,QAGjBrB,EAAM0C,IAAG,SAAUC,EAAe,UAAC9D,KAAAoE,SAAAA,MAAAA,EAChC,OAAAL,EAAA,EAAJ,IAAI,EAAA,CAAA,IAAAM,EAAA,WAHb,GAAIL,EAAI,EAAC3E,OAAAA,QAAAmD,QAAQI,EAAM,KAAG5C,KAAA,WAAA,EAAC,CAGd,UAHcqE,GAAAA,EAAArE,KAAAqE,EAAArE,KAAAmE,GAAAA,GAK7B,GAAC,OAAAF,GAAAA,EAAAjE,KAAAiE,EAAAjE,KAAA,SAAAsE,GAAAP,OAAAA,EAAAO,EAEM,IAAI,GAAAP,EAAAE,EAAJ,IAAI,OAAAM,EAAA,WAAA,GAvBPf,EAAS,OAAAnE,QAAAmD,QACEX,EAAUC,EAAG,WAAA,WAAazC,QAAAmD,6HAAAgC,CAEtBzC,EAAE0C,SAAAA,EAAAC,GAAA,OAAArF,QAAAmD,QAETrB,EAAMwD,aAAa1B,EAAE,QAAS,IAAK,KAAM,KAAGjD,KAAAX,WAAAA,OAAAA,QAAAmD,QAC5CrB,EAAMsC,OAAOH,EAAmB,IAAEtD,mBAAAyE,EAAA,MAAAC,EAAAA,OAAAA,CAAA,OAE5C,CAAC,MAAAtF,GAAA,OAAAC,QAAA0D,OAAA3D,OAACY,cAAA4E,GAAA,OAAAlB,EAAA,EAAAkB,CAAA,EAAA,CAeO,GAfP,OAAAL,GAAAA,EAAAvE,KAAAuE,EAAAvE,KAAA2D,GAAAA,EAAAY,EAAA,EAAA,EAgBN,CAAC,MAAAnF,UAAAC,QAAA0D,OAAA3D,EAAA,CAAA,EAoBD,MAAO,CACLyC,UAAAA,EACAmB,OAAAA,EACA6B,yBArB8B/C,EAAaC,GAC3C,IAAI+C,EAAQ,OAAUhE,EAAYgB,IAAAA,EAAM,OAAAzC,QAAAmD,QAExBQ,EAAOlB,EAAG,WAAA,WAAazC,QAAAmD,QACrBT,KAAI/B,cAAhB+E,GAAG,OAAA1F,QAAAmD,QAEDrB,EAAMwD,IAAIG,EAAUE,EAAAA,QAAUC,UAAUF,GAAM,KAAM,KAAG/E,gBAE7D,OAAO+E,CAAI,EACb,EAAA,CAAC,MAAA3F,GAAA,OAAAC,QAAA0D,OAAA3D,EAAC,CAAA,IAAAY,KANE+E,SAAAA,OAAGG,EAAAC,EAAA,WAAA,GAQI,MAAPJ,EAAWK,CAAAA,IAAAA,EACNJ,EAAS,QAACK,MAAKhG,OAAAA,QAAAmD,QAAQrB,EAAM0C,IAAIiB,IAAS9E,KAAAsF,SAAAA,GAAAC,IAAAA,EAAAH,EAAAI,KAA1CR,EAAS,QAAAM,GAAA,OAAAJ,EAAA,EAAAK,CAAA,EAAA,CAAA,CATX,GASW,OAAAJ,GAAAA,EAAAnF,KAAAmF,EAAAnF,KAAAyF,SAAAA,GAAAP,OAAAA,EAAAO,EAGXV,CAAG,GAAAG,EAAAC,EAAHJ,CAAG,EACZ,EAOF"}
1
+ {"version":3,"file":"index.cjs","sources":["../src/index.ts"],"sourcesContent":["import { delay } from '@lowerdeck/delay';\nimport { parseRedisUrl } from '@lowerdeck/redis';\nimport { Redis } from 'ioredis';\n\n// @ts-ignore\nimport SuperJSON from 'superjson';\n\n// @ts-ignore\nimport Redlock_ from 'redlock';\n\nexport let createLock = ({ name, redisUrl }: { name: string; redisUrl: string }) => {\n let nameHash = Bun.hash.cityHash32(name);\n let redis = new Redis(parseRedisUrl(redisUrl));\n\n let redlock = new Redlock_([redis as any], {\n // The expected clock drift; for more details see:\n // http://redis.io/topics/distlock\n driftFactor: 0.01, // multiplied by lock ttl to determine drift time\n\n // The max number of times Redlock will attempt to lock a resource\n // before erroring.\n retryCount: 50,\n\n // the time in ms between attempts\n retryDelay: 200, // time in ms\n\n // the max time in ms randomly added to retries\n // to improve performance under high contention\n // see https://www.awsarchitectureblog.com/2015/03/backoff.html\n retryJitter: 200, // time in ms\n\n // The minimum remaining time on a lock before an extension is automatically\n // attempted with the `using` API.\n automaticExtensionThreshold: 500\n } as any);\n\n let usingLock = async <T>(\n key: string | string[],\n fn: (controller: { passForNow: () => void }) => Promise<T>\n ): Promise<T> => {\n let keyArray = (Array.isArray(key) ? key : [key]).map(k => `l:${nameHash}:${k}`);\n\n let runLock = async () => {\n let passingForNow = false;\n let passForNow = () => {\n passingForNow = true;\n };\n\n let result = await redlock.using(keyArray, 10_000, () => fn({ passForNow }));\n\n if (passingForNow) {\n await delay(100);\n return runLock();\n }\n\n return result;\n };\n\n return runLock();\n };\n\n let doOnce = async <T>(key: string, fn: () => Promise<T>): Promise<T | null> => {\n let id = `${nameHash}:${Math.random()}:${Date.now()}`;\n let uniquenessHashKey = `luniq:${nameHash}:${key}`;\n\n let keyWasSet = await redis.setnx(uniquenessHashKey, id);\n await redis.expire(uniquenessHashKey, 60 * 5);\n\n if (keyWasSet) {\n return await usingLock(key, async () => {\n try {\n return await fn();\n } finally {\n await redis.set(`luniq:${id}:done`, '1', 'EX', 10);\n await redis.expire(uniquenessHashKey, 5);\n }\n });\n }\n\n let winnerId = await redis.get(uniquenessHashKey);\n if (!winnerId) return null;\n\n // If we lost, we'll wait for the winner to finish.\n for (let i = 0; i < 25; i++) {\n if (i > 0) await delay(25);\n\n if (await redis.get(`luniq:${winnerId}:done`)) {\n return null;\n }\n }\n\n return null;\n };\n\n let doOnceAndReturn = async <T>(key: string, fn: () => Promise<T>): Promise<T> => {\n let redisKey = `doa:${nameHash}:${key}`;\n\n let res = await doOnce(key, async () => {\n let res = await fn();\n\n await redis.set(redisKey, SuperJSON.stringify(res), 'EX', 60);\n\n return res;\n });\n\n if (res == null) {\n return SuperJSON.parse((await redis.get(redisKey)) as string);\n }\n\n return res;\n };\n\n return {\n usingLock,\n doOnce,\n doOnceAndReturn\n };\n};\n"],"names":["_settle","state","value","pact","s","_Pact","o","v","then","bind","observer","prototype","onFulfilled","onRejected","result","this","callback","e","_this","_isSettledPact","thenable","_ref","redisUrl","nameHash","Bun","hash","cityHash32","name","redis","Redis","parseRedisUrl","redlock","Redlock_","driftFactor","retryCount","retryDelay","retryJitter","automaticExtensionThreshold","usingLock","key","fn","keyArray","Array","isArray","map","k","runLock","passingForNow","passForNow","Promise","resolve","using","_exit","_temp","delay","_runLock","_result","reject","doOnce","id","Math","random","Date","now","uniquenessHashKey","setnx","keyWasSet","expire","_exit2","_temp7","_result2","get","winnerId","_exit3","i","_temp5","_for","_temp4","_redis$get","_temp3","_result3","_temp6","_finallyRethrows","_wasThrown","_result4","set","_await$usingLock","doOnceAndReturn","redisKey","res","SuperJSON","stringify","_exit4","_temp8","_parse","parse","_redis$get2","_SuperJSON$parse","call","_result5"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{parseRedisUrl as n}from"@lowerdeck/redis";import{Redis as r}from"ioredis";import t from"superjson";import e from"redlock";var i=function(n){return new Promise(function(r){return setTimeout(r,n)})};function o(n,r,t){if(!n.s){if(t instanceof u){if(!t.s)return void(t.o=o.bind(null,n,r));1&r&&(r=t.s),t=t.v}if(t&&t.then)return void t.then(o.bind(null,n,r),o.bind(null,n,2));n.s=r,n.v=t;const e=n.o;e&&e(n)}}var u=/*#__PURE__*/function(){function n(){}return n.prototype.then=function(r,t){var e=new n,i=this.s;if(i){var u=1&i?r:t;if(u){try{o(e,1,u(this.v))}catch(n){o(e,2,n)}return e}return this}return this.o=function(n){try{var i=n.v;1&n.s?o(e,1,r?r(i):i):t?o(e,1,t(i)):o(e,2,i)}catch(n){o(e,2,n)}},e},n}();function c(n){return n instanceof u&&1&n.s}var f=function(f){var h=f.redisUrl,s=Bun.hash.cityHash32(f.name),v=new r(n(h)),a=new e([v],{driftFactor:.01,retryCount:50,retryDelay:200,retryJitter:200,automaticExtensionThreshold:500}),l=function(n,r){try{var t=(Array.isArray(n)?n:[n]).map(function(n){return"l:"+s+":"+n}),e=function(){try{var n=!1,o=function(){n=!0};return Promise.resolve(a.using(t,1e4,function(){return r({passForNow:o})})).then(function(r){var t,o=function(){if(n)return Promise.resolve(i(100)).then(function(){var n=e();return t=1,n})}();return o&&o.then?o.then(function(n){return t?n:r}):t?o:r})}catch(n){return Promise.reject(n)}};return e()}catch(n){return Promise.reject(n)}},m=function(n,r){try{var t=s+":"+Math.random()+":"+Date.now(),e="luniq:"+s+":"+n;return Promise.resolve(v.setnx(e,t)).then(function(f){return Promise.resolve(v.expire(e,300)).then(function(){var h;function s(n){return h?n:Promise.resolve(v.get(e)).then(function(n){var r;if(!n)return null;var t=0,e=function(n,r,t){for(var e;;){var i=n();if(c(i)&&(i=i.v),!i)return f;if(i.then){e=0;break}var f=t();if(f&&f.then){if(!c(f)){e=1;break}f=f.s}if(r){var h=r();if(h&&h.then&&!c(h)){e=2;break}}}var s=new u,v=o.bind(null,s,2);return(0===e?i.then(l):1===e?f.then(a):h.then(m)).then(void 0,v),s;function a(e){f=e;do{if(r&&(h=r())&&h.then&&!c(h))return void h.then(m).then(void 0,v);if(!(i=n())||c(i)&&!i.v)return void o(s,1,f);if(i.then)return void i.then(l).then(void 0,v);c(f=t())&&(f=f.v)}while(!f||!f.then);f.then(a).then(void 0,v)}function l(n){n?(f=t())&&f.then?f.then(a).then(void 0,v):a(f):o(s,1,f)}function m(){(i=n())?i.then?i.then(l).then(void 0,v):l(i):o(s,1,f)}}(function(){return!r&&t<25},function(){return t++},function(){function e(){return Promise.resolve(v.get("luniq:"+n+":done")).then(function(n){if(n)return r=1,null})}var o=function(){if(t>0)return Promise.resolve(i(25)).then(function(){})}();return o&&o.then?o.then(e):e()});return e&&e.then?e.then(function(n){return r?n:null}):r?e:null})}var a=function(){if(f)return Promise.resolve(l(n,function(){try{return Promise.resolve(function(n,r){try{var t=n()}catch(n){return r(!0,n)}return t&&t.then?t.then(r.bind(null,!1),r.bind(null,!0)):r(!1,t)}(r,function(n,r){return Promise.resolve(v.set("luniq:"+t+":done","1","EX",10)).then(function(){return Promise.resolve(v.expire(e,5)).then(function(){if(n)throw r;return r})})}))}catch(n){return Promise.reject(n)}})).then(function(n){return h=1,n})}();return a&&a.then?a.then(s):s(a)})})}catch(n){return Promise.reject(n)}};return{usingLock:l,doOnce:m,doOnceAndReturn:function(n,r){var e="doa:"+s+":"+n;return Promise.resolve(m(n,function(){try{return Promise.resolve(r()).then(function(n){return Promise.resolve(v.set(e,t.stringify(n),"EX",60)).then(function(){return n})})}catch(n){return Promise.reject(n)}})).then(function(n){var r,i=function(){if(null==n){var i=t.parse;return Promise.resolve(v.get(e)).then(function(n){var e=i.call(t,n);return r=1,e})}}();return i&&i.then?i.then(function(t){return r?t:n}):r?i:n})}}};export{f as createLock};
1
+ import{delay as n}from"@lowerdeck/delay";import{parseRedisUrl as r}from"@lowerdeck/redis";import{Redis as e}from"ioredis";import t from"superjson";import i from"redlock";function o(n,r,e){if(!n.s){if(e instanceof u){if(!e.s)return void(e.o=o.bind(null,n,r));1&r&&(r=e.s),e=e.v}if(e&&e.then)return void e.then(o.bind(null,n,r),o.bind(null,n,2));n.s=r,n.v=e;const t=n.o;t&&t(n)}}var u=/*#__PURE__*/function(){function n(){}return n.prototype.then=function(r,e){var t=new n,i=this.s;if(i){var u=1&i?r:e;if(u){try{o(t,1,u(this.v))}catch(n){o(t,2,n)}return t}return this}return this.o=function(n){try{var i=n.v;1&n.s?o(t,1,r?r(i):i):e?o(t,1,e(i)):o(t,2,i)}catch(n){o(t,2,n)}},t},n}();function c(n){return n instanceof u&&1&n.s}var f=function(f){var h=f.redisUrl,s=Bun.hash.cityHash32(f.name),v=new e(r(h)),a=new i([v],{driftFactor:.01,retryCount:50,retryDelay:200,retryJitter:200,automaticExtensionThreshold:500}),l=function(r,e){try{var t=(Array.isArray(r)?r:[r]).map(function(n){return"l:"+s+":"+n}),i=function(){try{var r=!1,o=function(){r=!0};return Promise.resolve(a.using(t,1e4,function(){return e({passForNow:o})})).then(function(e){var t,o=function(){if(r)return Promise.resolve(n(100)).then(function(){var n=i();return t=1,n})}();return o&&o.then?o.then(function(n){return t?n:e}):t?o:e})}catch(n){return Promise.reject(n)}};return i()}catch(n){return Promise.reject(n)}},d=function(r,e){try{var t=s+":"+Math.random()+":"+Date.now(),i="luniq:"+s+":"+r;return Promise.resolve(v.setnx(i,t)).then(function(f){return Promise.resolve(v.expire(i,300)).then(function(){var h;function s(r){return h?r:Promise.resolve(v.get(i)).then(function(r){var e;if(!r)return null;var t=0,i=function(n,r,e){for(var t;;){var i=n();if(c(i)&&(i=i.v),!i)return f;if(i.then){t=0;break}var f=e();if(f&&f.then){if(!c(f)){t=1;break}f=f.s}if(r){var h=r();if(h&&h.then&&!c(h)){t=2;break}}}var s=new u,v=o.bind(null,s,2);return(0===t?i.then(l):1===t?f.then(a):h.then(d)).then(void 0,v),s;function a(t){f=t;do{if(r&&(h=r())&&h.then&&!c(h))return void h.then(d).then(void 0,v);if(!(i=n())||c(i)&&!i.v)return void o(s,1,f);if(i.then)return void i.then(l).then(void 0,v);c(f=e())&&(f=f.v)}while(!f||!f.then);f.then(a).then(void 0,v)}function l(n){n?(f=e())&&f.then?f.then(a).then(void 0,v):a(f):o(s,1,f)}function d(){(i=n())?i.then?i.then(l).then(void 0,v):l(i):o(s,1,f)}}(function(){return!e&&t<25},function(){return t++},function(){function i(){return Promise.resolve(v.get("luniq:"+r+":done")).then(function(n){if(n)return e=1,null})}var o=function(){if(t>0)return Promise.resolve(n(25)).then(function(){})}();return o&&o.then?o.then(i):i()});return i&&i.then?i.then(function(n){return e?n:null}):e?i:null})}var a=function(){if(f)return Promise.resolve(l(r,function(){try{return Promise.resolve(function(n,r){try{var e=n()}catch(n){return r(!0,n)}return e&&e.then?e.then(r.bind(null,!1),r.bind(null,!0)):r(!1,e)}(e,function(n,r){return Promise.resolve(v.set("luniq:"+t+":done","1","EX",10)).then(function(){return Promise.resolve(v.expire(i,5)).then(function(){if(n)throw r;return r})})}))}catch(n){return Promise.reject(n)}})).then(function(n){return h=1,n})}();return a&&a.then?a.then(s):s(a)})})}catch(n){return Promise.reject(n)}};return{usingLock:l,doOnce:d,doOnceAndReturn:function(n,r){var e="doa:"+s+":"+n;return Promise.resolve(d(n,function(){try{return Promise.resolve(r()).then(function(n){return Promise.resolve(v.set(e,t.stringify(n),"EX",60)).then(function(){return n})})}catch(n){return Promise.reject(n)}})).then(function(n){var r,i=function(){if(null==n){var i=t.parse;return Promise.resolve(v.get(e)).then(function(n){var e=i.call(t,n);return r=1,e})}}();return i&&i.then?i.then(function(e){return r?e:n}):r?i:n})}}};export{f as createLock};
2
2
  //# sourceMappingURL=index.module.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.module.js","sources":["../../delay/dist/index.module.js","../src/index.ts"],"sourcesContent":["var e=function(e){return new Promise(function(n){return setTimeout(n,e)})};export{e as delay};\n//# sourceMappingURL=index.module.js.map\n","import { delay } from '@lowerdeck/delay';\nimport { parseRedisUrl } from '@lowerdeck/redis';\nimport { Redis } from 'ioredis';\n\n// @ts-ignore\nimport SuperJSON from 'superjson';\n\n// @ts-ignore\nimport Redlock_ from 'redlock';\n\nexport let createLock = ({ name, redisUrl }: { name: string; redisUrl: string }) => {\n let nameHash = Bun.hash.cityHash32(name);\n let redis = new Redis(parseRedisUrl(redisUrl));\n\n let redlock = new Redlock_([redis as any], {\n // The expected clock drift; for more details see:\n // http://redis.io/topics/distlock\n driftFactor: 0.01, // multiplied by lock ttl to determine drift time\n\n // The max number of times Redlock will attempt to lock a resource\n // before erroring.\n retryCount: 50,\n\n // the time in ms between attempts\n retryDelay: 200, // time in ms\n\n // the max time in ms randomly added to retries\n // to improve performance under high contention\n // see https://www.awsarchitectureblog.com/2015/03/backoff.html\n retryJitter: 200, // time in ms\n\n // The minimum remaining time on a lock before an extension is automatically\n // attempted with the `using` API.\n automaticExtensionThreshold: 500\n } as any);\n\n let usingLock = async <T>(\n key: string | string[],\n fn: (controller: { passForNow: () => void }) => Promise<T>\n ): Promise<T> => {\n let keyArray = (Array.isArray(key) ? key : [key]).map(k => `l:${nameHash}:${k}`);\n\n let runLock = async () => {\n let passingForNow = false;\n let passForNow = () => {\n passingForNow = true;\n };\n\n let result = await redlock.using(keyArray, 10_000, () => fn({ passForNow }));\n\n if (passingForNow) {\n await delay(100);\n return runLock();\n }\n\n return result;\n };\n\n return runLock();\n };\n\n let doOnce = async <T>(key: string, fn: () => Promise<T>): Promise<T | null> => {\n let id = `${nameHash}:${Math.random()}:${Date.now()}`;\n let uniquenessHashKey = `luniq:${nameHash}:${key}`;\n\n let keyWasSet = await redis.setnx(uniquenessHashKey, id);\n await redis.expire(uniquenessHashKey, 60 * 5);\n\n if (keyWasSet) {\n return await usingLock(key, async () => {\n try {\n return await fn();\n } finally {\n await redis.set(`luniq:${id}:done`, '1', 'EX', 10);\n await redis.expire(uniquenessHashKey, 5);\n }\n });\n }\n\n let winnerId = await redis.get(uniquenessHashKey);\n if (!winnerId) return null;\n\n // If we lost, we'll wait for the winner to finish.\n for (let i = 0; i < 25; i++) {\n if (i > 0) await delay(25);\n\n if (await redis.get(`luniq:${winnerId}:done`)) {\n return null;\n }\n }\n\n return null;\n };\n\n let doOnceAndReturn = async <T>(key: string, fn: () => Promise<T>): Promise<T> => {\n let redisKey = `doa:${nameHash}:${key}`;\n\n let res = await doOnce(key, async () => {\n let res = await fn();\n\n await redis.set(redisKey, SuperJSON.stringify(res), 'EX', 60);\n\n return res;\n });\n\n if (res == null) {\n return SuperJSON.parse((await redis.get(redisKey)) as string);\n }\n\n return res;\n };\n\n return {\n usingLock,\n doOnce,\n doOnceAndReturn\n };\n};\n"],"names":["e","Promise","n","setTimeout","_settle","state","value","pact","s","_Pact","o","v","then","bind","observer","prototype","onFulfilled","onRejected","result","this","callback","_this","_isSettledPact","thenable","createLock","_ref","redisUrl","nameHash","Bun","hash","cityHash32","name","redis","Redis","parseRedisUrl","redlock","Redlock_","driftFactor","retryCount","retryDelay","retryJitter","automaticExtensionThreshold","usingLock","key","fn","keyArray","Array","isArray","map","k","runLock","passingForNow","passForNow","resolve","using","_exit","_temp","delay","_runLock","_result","reject","doOnce","id","Math","random","Date","now","uniquenessHashKey","setnx","keyWasSet","expire","_exit2","_temp7","_result2","get","winnerId","_exit3","i","_temp5","_for","_temp4","_redis$get","_temp3","_result3","_temp6","_finallyRethrows","_wasThrown","_result4","set","_await$usingLock","doOnceAndReturn","redisKey","res","SuperJSON","stringify","_exit4","_temp8","_parse","parse","_redis$get2","_SuperJSON$parse","call","_result5"],"mappings":"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"}
1
+ {"version":3,"file":"index.module.js","sources":["../src/index.ts"],"sourcesContent":["import { delay } from '@lowerdeck/delay';\nimport { parseRedisUrl } from '@lowerdeck/redis';\nimport { Redis } from 'ioredis';\n\n// @ts-ignore\nimport SuperJSON from 'superjson';\n\n// @ts-ignore\nimport Redlock_ from 'redlock';\n\nexport let createLock = ({ name, redisUrl }: { name: string; redisUrl: string }) => {\n let nameHash = Bun.hash.cityHash32(name);\n let redis = new Redis(parseRedisUrl(redisUrl));\n\n let redlock = new Redlock_([redis as any], {\n // The expected clock drift; for more details see:\n // http://redis.io/topics/distlock\n driftFactor: 0.01, // multiplied by lock ttl to determine drift time\n\n // The max number of times Redlock will attempt to lock a resource\n // before erroring.\n retryCount: 50,\n\n // the time in ms between attempts\n retryDelay: 200, // time in ms\n\n // the max time in ms randomly added to retries\n // to improve performance under high contention\n // see https://www.awsarchitectureblog.com/2015/03/backoff.html\n retryJitter: 200, // time in ms\n\n // The minimum remaining time on a lock before an extension is automatically\n // attempted with the `using` API.\n automaticExtensionThreshold: 500\n } as any);\n\n let usingLock = async <T>(\n key: string | string[],\n fn: (controller: { passForNow: () => void }) => Promise<T>\n ): Promise<T> => {\n let keyArray = (Array.isArray(key) ? key : [key]).map(k => `l:${nameHash}:${k}`);\n\n let runLock = async () => {\n let passingForNow = false;\n let passForNow = () => {\n passingForNow = true;\n };\n\n let result = await redlock.using(keyArray, 10_000, () => fn({ passForNow }));\n\n if (passingForNow) {\n await delay(100);\n return runLock();\n }\n\n return result;\n };\n\n return runLock();\n };\n\n let doOnce = async <T>(key: string, fn: () => Promise<T>): Promise<T | null> => {\n let id = `${nameHash}:${Math.random()}:${Date.now()}`;\n let uniquenessHashKey = `luniq:${nameHash}:${key}`;\n\n let keyWasSet = await redis.setnx(uniquenessHashKey, id);\n await redis.expire(uniquenessHashKey, 60 * 5);\n\n if (keyWasSet) {\n return await usingLock(key, async () => {\n try {\n return await fn();\n } finally {\n await redis.set(`luniq:${id}:done`, '1', 'EX', 10);\n await redis.expire(uniquenessHashKey, 5);\n }\n });\n }\n\n let winnerId = await redis.get(uniquenessHashKey);\n if (!winnerId) return null;\n\n // If we lost, we'll wait for the winner to finish.\n for (let i = 0; i < 25; i++) {\n if (i > 0) await delay(25);\n\n if (await redis.get(`luniq:${winnerId}:done`)) {\n return null;\n }\n }\n\n return null;\n };\n\n let doOnceAndReturn = async <T>(key: string, fn: () => Promise<T>): Promise<T> => {\n let redisKey = `doa:${nameHash}:${key}`;\n\n let res = await doOnce(key, async () => {\n let res = await fn();\n\n await redis.set(redisKey, SuperJSON.stringify(res), 'EX', 60);\n\n return res;\n });\n\n if (res == null) {\n return SuperJSON.parse((await redis.get(redisKey)) as string);\n }\n\n return res;\n };\n\n return {\n usingLock,\n doOnce,\n doOnceAndReturn\n };\n};\n"],"names":["_settle","state","value","pact","s","_Pact","o","v","then","bind","observer","prototype","onFulfilled","onRejected","result","this","callback","e","_this","_isSettledPact","thenable","createLock","_ref","redisUrl","nameHash","Bun","hash","cityHash32","name","redis","Redis","parseRedisUrl","redlock","Redlock_","driftFactor","retryCount","retryDelay","retryJitter","automaticExtensionThreshold","usingLock","key","fn","keyArray","Array","isArray","map","k","runLock","passingForNow","passForNow","Promise","resolve","using","_exit","_temp","delay","_runLock","_result","reject","doOnce","id","Math","random","Date","now","uniquenessHashKey","setnx","keyWasSet","expire","_exit2","_temp7","_result2","get","winnerId","_exit3","i","_temp5","_for","_temp4","_redis$get","_temp3","_result3","_temp6","_finallyRethrows","_wasThrown","_result4","set","_await$usingLock","doOnceAndReturn","redisKey","res","SuperJSON","stringify","_exit4","_temp8","_parse","parse","_redis$get2","_SuperJSON$parse","call","_result5"],"mappings":"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"}
package/dist/index.umd.js CHANGED
@@ -1,2 +1,2 @@
1
- !function(n,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("@lowerdeck/redis"),require("ioredis"),require("superjson"),require("redlock")):"function"==typeof define&&define.amd?define(["exports","@lowerdeck/redis","ioredis","superjson","redlock"],e):e((n||self).lock={},n.redis,n.ioredis,n.superjson,n.redlock)}(this,function(n,e,r,t,i){function o(n){return n&&"object"==typeof n&&"default"in n?n:{default:n}}var u=/*#__PURE__*/o(t),f=/*#__PURE__*/o(i),c=function(n){return new Promise(function(e){return setTimeout(e,n)})};function s(n,e,r){if(!n.s){if(r instanceof h){if(!r.s)return void(r.o=s.bind(null,n,e));1&e&&(e=r.s),r=r.v}if(r&&r.then)return void r.then(s.bind(null,n,e),s.bind(null,n,2));n.s=e,n.v=r;const t=n.o;t&&t(n)}}var h=/*#__PURE__*/function(){function n(){}return n.prototype.then=function(e,r){var t=new n,i=this.s;if(i){var o=1&i?e:r;if(o){try{s(t,1,o(this.v))}catch(n){s(t,2,n)}return t}return this}return this.o=function(n){try{var i=n.v;1&n.s?s(t,1,e?e(i):i):r?s(t,1,r(i)):s(t,2,i)}catch(n){s(t,2,n)}},t},n}();function a(n){return n instanceof h&&1&n.s}n.createLock=function(n){var t=n.redisUrl,i=Bun.hash.cityHash32(n.name),o=new r.Redis(e.parseRedisUrl(t)),l=new f.default([o],{driftFactor:.01,retryCount:50,retryDelay:200,retryJitter:200,automaticExtensionThreshold:500}),v=function(n,e){try{var r=(Array.isArray(n)?n:[n]).map(function(n){return"l:"+i+":"+n}),t=function(){try{var n=!1,i=function(){n=!0};return Promise.resolve(l.using(r,1e4,function(){return e({passForNow:i})})).then(function(e){var r,i=function(){if(n)return Promise.resolve(c(100)).then(function(){var n=t();return r=1,n})}();return i&&i.then?i.then(function(n){return r?n:e}):r?i:e})}catch(n){return Promise.reject(n)}};return t()}catch(n){return Promise.reject(n)}},d=function(n,e){try{var r=i+":"+Math.random()+":"+Date.now(),t="luniq:"+i+":"+n;return Promise.resolve(o.setnx(t,r)).then(function(i){return Promise.resolve(o.expire(t,300)).then(function(){var u;function f(n){return u?n:Promise.resolve(o.get(t)).then(function(n){var e;if(!n)return null;var r=0,t=function(n,e,r){for(var t;;){var i=n();if(a(i)&&(i=i.v),!i)return o;if(i.then){t=0;break}var o=r();if(o&&o.then){if(!a(o)){t=1;break}o=o.s}if(e){var u=e();if(u&&u.then&&!a(u)){t=2;break}}}var f=new h,c=s.bind(null,f,2);return(0===t?i.then(v):1===t?o.then(l):u.then(d)).then(void 0,c),f;function l(t){o=t;do{if(e&&(u=e())&&u.then&&!a(u))return void u.then(d).then(void 0,c);if(!(i=n())||a(i)&&!i.v)return void s(f,1,o);if(i.then)return void i.then(v).then(void 0,c);a(o=r())&&(o=o.v)}while(!o||!o.then);o.then(l).then(void 0,c)}function v(n){n?(o=r())&&o.then?o.then(l).then(void 0,c):l(o):s(f,1,o)}function d(){(i=n())?i.then?i.then(v).then(void 0,c):v(i):s(f,1,o)}}(function(){return!e&&r<25},function(){return r++},function(){function t(){return Promise.resolve(o.get("luniq:"+n+":done")).then(function(n){if(n)return e=1,null})}var i=function(){if(r>0)return Promise.resolve(c(25)).then(function(){})}();return i&&i.then?i.then(t):t()});return t&&t.then?t.then(function(n){return e?n:null}):e?t:null})}var l=function(){if(i)return Promise.resolve(v(n,function(){try{return Promise.resolve(function(n,e){try{var r=n()}catch(n){return e(!0,n)}return r&&r.then?r.then(e.bind(null,!1),e.bind(null,!0)):e(!1,r)}(e,function(n,e){return Promise.resolve(o.set("luniq:"+r+":done","1","EX",10)).then(function(){return Promise.resolve(o.expire(t,5)).then(function(){if(n)throw e;return e})})}))}catch(n){return Promise.reject(n)}})).then(function(n){return u=1,n})}();return l&&l.then?l.then(f):f(l)})})}catch(n){return Promise.reject(n)}};return{usingLock:v,doOnce:d,doOnceAndReturn:function(n,e){var r="doa:"+i+":"+n;return Promise.resolve(d(n,function(){try{return Promise.resolve(e()).then(function(n){return Promise.resolve(o.set(r,u.default.stringify(n),"EX",60)).then(function(){return n})})}catch(n){return Promise.reject(n)}})).then(function(n){var e,t=function(){if(null==n){var t=u.default.parse;return Promise.resolve(o.get(r)).then(function(n){var r=t.call(u.default,n);return e=1,r})}}();return t&&t.then?t.then(function(r){return e?r:n}):e?t:n})}}}});
1
+ !function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports,require("@lowerdeck/delay"),require("@lowerdeck/redis"),require("ioredis"),require("superjson"),require("redlock")):"function"==typeof define&&define.amd?define(["exports","@lowerdeck/delay","@lowerdeck/redis","ioredis","superjson","redlock"],n):n((e||self).lock={},e.delay,e.redis,e.ioredis,e.superjson,e.redlock)}(this,function(e,n,r,t,i,o){function u(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var f=/*#__PURE__*/u(i),c=/*#__PURE__*/u(o);function s(e,n,r){if(!e.s){if(r instanceof h){if(!r.s)return void(r.o=s.bind(null,e,n));1&n&&(n=r.s),r=r.v}if(r&&r.then)return void r.then(s.bind(null,e,n),s.bind(null,e,2));e.s=n,e.v=r;const t=e.o;t&&t(e)}}var h=/*#__PURE__*/function(){function e(){}return e.prototype.then=function(n,r){var t=new e,i=this.s;if(i){var o=1&i?n:r;if(o){try{s(t,1,o(this.v))}catch(e){s(t,2,e)}return t}return this}return this.o=function(e){try{var i=e.v;1&e.s?s(t,1,n?n(i):i):r?s(t,1,r(i)):s(t,2,i)}catch(e){s(t,2,e)}},t},e}();function l(e){return e instanceof h&&1&e.s}e.createLock=function(e){var i=e.redisUrl,o=Bun.hash.cityHash32(e.name),u=new t.Redis(r.parseRedisUrl(i)),a=new c.default([u],{driftFactor:.01,retryCount:50,retryDelay:200,retryJitter:200,automaticExtensionThreshold:500}),d=function(e,r){try{var t=(Array.isArray(e)?e:[e]).map(function(e){return"l:"+o+":"+e}),i=function(){try{var e=!1,o=function(){e=!0};return Promise.resolve(a.using(t,1e4,function(){return r({passForNow:o})})).then(function(r){var t,o=function(){if(e)return Promise.resolve(n.delay(100)).then(function(){var e=i();return t=1,e})}();return o&&o.then?o.then(function(e){return t?e:r}):t?o:r})}catch(e){return Promise.reject(e)}};return i()}catch(e){return Promise.reject(e)}},v=function(e,r){try{var t=o+":"+Math.random()+":"+Date.now(),i="luniq:"+o+":"+e;return Promise.resolve(u.setnx(i,t)).then(function(o){return Promise.resolve(u.expire(i,300)).then(function(){var f;function c(e){return f?e:Promise.resolve(u.get(i)).then(function(e){var r;if(!e)return null;var t=0,i=function(e,n,r){for(var t;;){var i=e();if(l(i)&&(i=i.v),!i)return o;if(i.then){t=0;break}var o=r();if(o&&o.then){if(!l(o)){t=1;break}o=o.s}if(n){var u=n();if(u&&u.then&&!l(u)){t=2;break}}}var f=new h,c=s.bind(null,f,2);return(0===t?i.then(d):1===t?o.then(a):u.then(v)).then(void 0,c),f;function a(t){o=t;do{if(n&&(u=n())&&u.then&&!l(u))return void u.then(v).then(void 0,c);if(!(i=e())||l(i)&&!i.v)return void s(f,1,o);if(i.then)return void i.then(d).then(void 0,c);l(o=r())&&(o=o.v)}while(!o||!o.then);o.then(a).then(void 0,c)}function d(e){e?(o=r())&&o.then?o.then(a).then(void 0,c):a(o):s(f,1,o)}function v(){(i=e())?i.then?i.then(d).then(void 0,c):d(i):s(f,1,o)}}(function(){return!r&&t<25},function(){return t++},function(){function i(){return Promise.resolve(u.get("luniq:"+e+":done")).then(function(e){if(e)return r=1,null})}var o=function(){if(t>0)return Promise.resolve(n.delay(25)).then(function(){})}();return o&&o.then?o.then(i):i()});return i&&i.then?i.then(function(e){return r?e:null}):r?i:null})}var a=function(){if(o)return Promise.resolve(d(e,function(){try{return Promise.resolve(function(e,n){try{var r=e()}catch(e){return n(!0,e)}return r&&r.then?r.then(n.bind(null,!1),n.bind(null,!0)):n(!1,r)}(r,function(e,n){return Promise.resolve(u.set("luniq:"+t+":done","1","EX",10)).then(function(){return Promise.resolve(u.expire(i,5)).then(function(){if(e)throw n;return n})})}))}catch(e){return Promise.reject(e)}})).then(function(e){return f=1,e})}();return a&&a.then?a.then(c):c(a)})})}catch(e){return Promise.reject(e)}};return{usingLock:d,doOnce:v,doOnceAndReturn:function(e,n){var r="doa:"+o+":"+e;return Promise.resolve(v(e,function(){try{return Promise.resolve(n()).then(function(e){return Promise.resolve(u.set(r,f.default.stringify(e),"EX",60)).then(function(){return e})})}catch(e){return Promise.reject(e)}})).then(function(e){var n,t=function(){if(null==e){var t=f.default.parse;return Promise.resolve(u.get(r)).then(function(e){var r=t.call(f.default,e);return n=1,r})}}();return t&&t.then?t.then(function(r){return n?r:e}):n?t:e})}}}});
2
2
  //# sourceMappingURL=index.umd.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.umd.js","sources":["../../delay/dist/index.module.js","../src/index.ts"],"sourcesContent":["var e=function(e){return new Promise(function(n){return setTimeout(n,e)})};export{e as delay};\n//# sourceMappingURL=index.module.js.map\n","import { delay } from '@lowerdeck/delay';\nimport { parseRedisUrl } from '@lowerdeck/redis';\nimport { Redis } from 'ioredis';\n\n// @ts-ignore\nimport SuperJSON from 'superjson';\n\n// @ts-ignore\nimport Redlock_ from 'redlock';\n\nexport let createLock = ({ name, redisUrl }: { name: string; redisUrl: string }) => {\n let nameHash = Bun.hash.cityHash32(name);\n let redis = new Redis(parseRedisUrl(redisUrl));\n\n let redlock = new Redlock_([redis as any], {\n // The expected clock drift; for more details see:\n // http://redis.io/topics/distlock\n driftFactor: 0.01, // multiplied by lock ttl to determine drift time\n\n // The max number of times Redlock will attempt to lock a resource\n // before erroring.\n retryCount: 50,\n\n // the time in ms between attempts\n retryDelay: 200, // time in ms\n\n // the max time in ms randomly added to retries\n // to improve performance under high contention\n // see https://www.awsarchitectureblog.com/2015/03/backoff.html\n retryJitter: 200, // time in ms\n\n // The minimum remaining time on a lock before an extension is automatically\n // attempted with the `using` API.\n automaticExtensionThreshold: 500\n } as any);\n\n let usingLock = async <T>(\n key: string | string[],\n fn: (controller: { passForNow: () => void }) => Promise<T>\n ): Promise<T> => {\n let keyArray = (Array.isArray(key) ? key : [key]).map(k => `l:${nameHash}:${k}`);\n\n let runLock = async () => {\n let passingForNow = false;\n let passForNow = () => {\n passingForNow = true;\n };\n\n let result = await redlock.using(keyArray, 10_000, () => fn({ passForNow }));\n\n if (passingForNow) {\n await delay(100);\n return runLock();\n }\n\n return result;\n };\n\n return runLock();\n };\n\n let doOnce = async <T>(key: string, fn: () => Promise<T>): Promise<T | null> => {\n let id = `${nameHash}:${Math.random()}:${Date.now()}`;\n let uniquenessHashKey = `luniq:${nameHash}:${key}`;\n\n let keyWasSet = await redis.setnx(uniquenessHashKey, id);\n await redis.expire(uniquenessHashKey, 60 * 5);\n\n if (keyWasSet) {\n return await usingLock(key, async () => {\n try {\n return await fn();\n } finally {\n await redis.set(`luniq:${id}:done`, '1', 'EX', 10);\n await redis.expire(uniquenessHashKey, 5);\n }\n });\n }\n\n let winnerId = await redis.get(uniquenessHashKey);\n if (!winnerId) return null;\n\n // If we lost, we'll wait for the winner to finish.\n for (let i = 0; i < 25; i++) {\n if (i > 0) await delay(25);\n\n if (await redis.get(`luniq:${winnerId}:done`)) {\n return null;\n }\n }\n\n return null;\n };\n\n let doOnceAndReturn = async <T>(key: string, fn: () => Promise<T>): Promise<T> => {\n let redisKey = `doa:${nameHash}:${key}`;\n\n let res = await doOnce(key, async () => {\n let res = await fn();\n\n await redis.set(redisKey, SuperJSON.stringify(res), 'EX', 60);\n\n return res;\n });\n\n if (res == null) {\n return SuperJSON.parse((await redis.get(redisKey)) as string);\n }\n\n return res;\n };\n\n return {\n usingLock,\n doOnce,\n doOnceAndReturn\n };\n};\n"],"names":["e","Promise","n","setTimeout","_settle","state","value","pact","s","_Pact","o","v","then","bind","observer","prototype","onFulfilled","onRejected","result","this","callback","_this","_isSettledPact","thenable","_ref","redisUrl","nameHash","Bun","hash","cityHash32","name","redis","Redis","parseRedisUrl","redlock","Redlock_","driftFactor","retryCount","retryDelay","retryJitter","automaticExtensionThreshold","usingLock","key","fn","keyArray","Array","isArray","map","k","runLock","passingForNow","passForNow","resolve","using","_exit","_temp","delay","_runLock","_result","reject","doOnce","id","Math","random","Date","now","uniquenessHashKey","setnx","keyWasSet","expire","_exit2","_temp7","_result2","get","winnerId","_exit3","i","_temp5","_for","_temp4","_redis$get","_temp3","_result3","_temp6","_finallyRethrows","_wasThrown","_result4","set","_await$usingLock","doOnceAndReturn","redisKey","res","SuperJSON","stringify","_exit4","_temp8","_parse","parse","_redis$get2","_SuperJSON$parse","call","_result5"],"mappings":"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"}
1
+ {"version":3,"file":"index.umd.js","sources":["../src/index.ts"],"sourcesContent":["import { delay } from '@lowerdeck/delay';\nimport { parseRedisUrl } from '@lowerdeck/redis';\nimport { Redis } from 'ioredis';\n\n// @ts-ignore\nimport SuperJSON from 'superjson';\n\n// @ts-ignore\nimport Redlock_ from 'redlock';\n\nexport let createLock = ({ name, redisUrl }: { name: string; redisUrl: string }) => {\n let nameHash = Bun.hash.cityHash32(name);\n let redis = new Redis(parseRedisUrl(redisUrl));\n\n let redlock = new Redlock_([redis as any], {\n // The expected clock drift; for more details see:\n // http://redis.io/topics/distlock\n driftFactor: 0.01, // multiplied by lock ttl to determine drift time\n\n // The max number of times Redlock will attempt to lock a resource\n // before erroring.\n retryCount: 50,\n\n // the time in ms between attempts\n retryDelay: 200, // time in ms\n\n // the max time in ms randomly added to retries\n // to improve performance under high contention\n // see https://www.awsarchitectureblog.com/2015/03/backoff.html\n retryJitter: 200, // time in ms\n\n // The minimum remaining time on a lock before an extension is automatically\n // attempted with the `using` API.\n automaticExtensionThreshold: 500\n } as any);\n\n let usingLock = async <T>(\n key: string | string[],\n fn: (controller: { passForNow: () => void }) => Promise<T>\n ): Promise<T> => {\n let keyArray = (Array.isArray(key) ? key : [key]).map(k => `l:${nameHash}:${k}`);\n\n let runLock = async () => {\n let passingForNow = false;\n let passForNow = () => {\n passingForNow = true;\n };\n\n let result = await redlock.using(keyArray, 10_000, () => fn({ passForNow }));\n\n if (passingForNow) {\n await delay(100);\n return runLock();\n }\n\n return result;\n };\n\n return runLock();\n };\n\n let doOnce = async <T>(key: string, fn: () => Promise<T>): Promise<T | null> => {\n let id = `${nameHash}:${Math.random()}:${Date.now()}`;\n let uniquenessHashKey = `luniq:${nameHash}:${key}`;\n\n let keyWasSet = await redis.setnx(uniquenessHashKey, id);\n await redis.expire(uniquenessHashKey, 60 * 5);\n\n if (keyWasSet) {\n return await usingLock(key, async () => {\n try {\n return await fn();\n } finally {\n await redis.set(`luniq:${id}:done`, '1', 'EX', 10);\n await redis.expire(uniquenessHashKey, 5);\n }\n });\n }\n\n let winnerId = await redis.get(uniquenessHashKey);\n if (!winnerId) return null;\n\n // If we lost, we'll wait for the winner to finish.\n for (let i = 0; i < 25; i++) {\n if (i > 0) await delay(25);\n\n if (await redis.get(`luniq:${winnerId}:done`)) {\n return null;\n }\n }\n\n return null;\n };\n\n let doOnceAndReturn = async <T>(key: string, fn: () => Promise<T>): Promise<T> => {\n let redisKey = `doa:${nameHash}:${key}`;\n\n let res = await doOnce(key, async () => {\n let res = await fn();\n\n await redis.set(redisKey, SuperJSON.stringify(res), 'EX', 60);\n\n return res;\n });\n\n if (res == null) {\n return SuperJSON.parse((await redis.get(redisKey)) as string);\n }\n\n return res;\n };\n\n return {\n usingLock,\n doOnce,\n doOnceAndReturn\n };\n};\n"],"names":["_settle","state","value","pact","s","_Pact","o","v","then","bind","observer","prototype","onFulfilled","onRejected","result","this","callback","e","_this","_isSettledPact","thenable","_ref","redisUrl","nameHash","Bun","hash","cityHash32","name","redis","Redis","parseRedisUrl","redlock","Redlock_","driftFactor","retryCount","retryDelay","retryJitter","automaticExtensionThreshold","usingLock","key","fn","keyArray","Array","isArray","map","k","runLock","passingForNow","passForNow","Promise","resolve","using","_exit","_temp","delay","_runLock","_result","reject","doOnce","id","Math","random","Date","now","uniquenessHashKey","setnx","keyWasSet","expire","_exit2","_temp7","_result2","get","winnerId","_exit3","i","_temp5","_for","_temp4","_redis$get","_temp3","_result3","_temp6","_finallyRethrows","_wasThrown","_result4","set","_await$usingLock","doOnceAndReturn","redisKey","res","SuperJSON","stringify","_exit4","_temp8","_parse","parse","_redis$get2","_SuperJSON$parse","call","_result5"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lowerdeck/lock",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -12,7 +12,7 @@
12
12
  "types": "./dist/index.d.ts",
13
13
  "require": "./dist/index.cjs",
14
14
  "import": "./dist/index.module.js",
15
- "default": "./dist/index.modern.js"
15
+ "default": "./dist/index.module.js"
16
16
  },
17
17
  "main": "./dist/index.cjs",
18
18
  "module": "./dist/index.module.js",
@@ -24,8 +24,8 @@
24
24
  "build": "microbundle"
25
25
  },
26
26
  "dependencies": {
27
- "@lowerdeck/redis": "^1.0.0",
28
- "@lowerdeck/delay": "^1.0.0",
27
+ "@lowerdeck/redis": "^1.0.2",
28
+ "@lowerdeck/delay": "^1.0.3",
29
29
  "@types/bun": "^1.2.11",
30
30
  "ioredis": "^5.4.1",
31
31
  "redlock": "^5.0.0-beta.2",