@zukhruf/fencing 0.3.36 → 0.3.38

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.
package/README.md CHANGED
@@ -114,7 +114,7 @@ const token = await tokens.next('product:42');
114
114
 
115
115
  A counter file can hold text that is not decimal digits. An example is the empty file that `@zukhruf/mutex` 0.2.0 or earlier can leave after a power loss, because those versions did not sync the file to the disk. Then `next` rejects with a `SyntaxError` that names the file, and the file stays as it is. Thus the tokens of a key never start again at 1, and the fenced resource never accepts the writes of a stale holder.
116
116
 
117
- `EpochTokenSource` puts the epoch in the high 32 bits and the counter in the low 32 bits, as ZooKeeper does in its `zxid`. Each token of a newer epoch is higher than each token of an older epoch. A new leader thus outranks all grants of the leader before it. The epoch must be from 0 to 2^31 − 1, so that each token fits a signed 64-bit integer. One epoch gives at most 2^32 − 1 tokens. After that, `next` throws a `RangeError`.
117
+ `EpochTokenSource` puts the epoch in the high 32 bits and the counter in the low 32 bits, as ZooKeeper does in its `zxid`. Each token of a newer epoch is higher than each token of an older epoch. A new leader thus outranks all grants of the leader before it. The epoch must be from 0 to 2^31 − 1, so that each token fits a signed 64-bit integer. One epoch gives at most 2^32 − 1 tokens. After that, `next` throws an `EpochExhaustedError`, which is a `RangeError` with the `epoch`. Only a new term, with a higher epoch, gives more tokens. Thus a leader that gets this error must end its term.
118
118
 
119
119
  ## A fenced lease
120
120
 
@@ -0,0 +1,6 @@
1
+ /** The term of this epoch gave all of its tokens. Only a new term, with a higher epoch, can give more tokens. */
2
+ export declare class EpochExhaustedError extends RangeError {
3
+ readonly epoch: bigint;
4
+ constructor(epoch: bigint);
5
+ }
6
+ //# sourceMappingURL=epoch-exhausted-error.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"epoch-exhausted-error.d.ts","sourceRoot":"","sources":["../src/epoch-exhausted-error.ts"],"names":[],"mappings":"AAAA,iHAAiH;AACjH,qBAAa,mBAAoB,SAAQ,UAAU;IACjD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;gBAEX,KAAK,EAAE,MAAM;CAK1B"}
@@ -0,0 +1,10 @@
1
+ /** The term of this epoch gave all of its tokens. Only a new term, with a higher epoch, can give more tokens. */
2
+ export class EpochExhaustedError extends RangeError {
3
+ epoch;
4
+ constructor(epoch) {
5
+ super(`Epoch ${epoch} has no tokens left.`);
6
+ this.name = 'EpochExhaustedError';
7
+ this.epoch = epoch;
8
+ }
9
+ }
10
+ //# sourceMappingURL=epoch-exhausted-error.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"epoch-exhausted-error.js","sourceRoot":"","sources":["../src/epoch-exhausted-error.ts"],"names":[],"mappings":"AAAA,iHAAiH;AACjH,MAAM,OAAO,mBAAoB,SAAQ,UAAU;IACxC,KAAK,CAAS;IAEvB,YAAY,KAAa;QACvB,KAAK,CAAC,SAAS,KAAK,sBAAsB,CAAC,CAAC;QAC5C,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;QAClC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;CACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"epoch-token-source.d.ts","sourceRoot":"","sources":["../src/epoch-token-source.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAMrD;;;;GAIG;AACH,qBAAa,gBAAiB,YAAW,WAAW;;gBAItC,KAAK,EAAE,MAAM;IAOnB,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;CAOhD"}
1
+ {"version":3,"file":"epoch-token-source.d.ts","sourceRoot":"","sources":["../src/epoch-token-source.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAMrD;;;;GAIG;AACH,qBAAa,gBAAiB,YAAW,WAAW;;gBAItC,KAAK,EAAE,MAAM;IAOnB,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;CAOhD"}
@@ -1,3 +1,4 @@
1
+ import { EpochExhaustedError } from "./epoch-exhausted-error.js";
1
2
  import { FencingToken } from "./fencing-token.js";
2
3
  const SEQUENCE_BITS = 32n;
3
4
  const EPOCH_LIMIT = 1n << 31n;
@@ -19,7 +20,7 @@ export class EpochTokenSource {
19
20
  async next(_key) {
20
21
  this.#sequence++;
21
22
  if (this.#sequence >= SEQUENCE_LIMIT) {
22
- throw new RangeError(`Epoch ${this.#epoch} has no tokens left.`);
23
+ throw new EpochExhaustedError(this.#epoch);
23
24
  }
24
25
  return new FencingToken((this.#epoch << SEQUENCE_BITS) | this.#sequence);
25
26
  }
@@ -1 +1 @@
1
- {"version":3,"file":"epoch-token-source.js","sourceRoot":"","sources":["../src/epoch-token-source.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGlD,MAAM,aAAa,GAAG,GAAG,CAAC;AAC1B,MAAM,WAAW,GAAG,EAAE,IAAI,GAAG,CAAC;AAC9B,MAAM,cAAc,GAAG,EAAE,IAAI,aAAa,CAAC;AAE3C;;;;GAIG;AACH,MAAM,OAAO,gBAAgB;IAClB,MAAM,CAAS;IACxB,SAAS,GAAG,EAAE,CAAC;IAEf,YAAY,KAAa;QACvB,IAAI,KAAK,GAAG,EAAE,IAAI,KAAK,IAAI,WAAW,EAAE,CAAC;YACvC,MAAM,IAAI,UAAU,CAAC,SAAS,KAAK,mBAAmB,WAAW,IAAI,CAAC,CAAC;QACzE,CAAC;QACD,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;IACtB,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,IAAY;QACrB,IAAI,CAAC,SAAS,EAAE,CAAC;QACjB,IAAI,IAAI,CAAC,SAAS,IAAI,cAAc,EAAE,CAAC;YACrC,MAAM,IAAI,UAAU,CAAC,SAAS,IAAI,CAAC,MAAM,sBAAsB,CAAC,CAAC;QACnE,CAAC;QACD,OAAO,IAAI,YAAY,CAAC,CAAC,IAAI,CAAC,MAAM,IAAI,aAAa,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC;IAC3E,CAAC;CACF"}
1
+ {"version":3,"file":"epoch-token-source.js","sourceRoot":"","sources":["../src/epoch-token-source.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGlD,MAAM,aAAa,GAAG,GAAG,CAAC;AAC1B,MAAM,WAAW,GAAG,EAAE,IAAI,GAAG,CAAC;AAC9B,MAAM,cAAc,GAAG,EAAE,IAAI,aAAa,CAAC;AAE3C;;;;GAIG;AACH,MAAM,OAAO,gBAAgB;IAClB,MAAM,CAAS;IACxB,SAAS,GAAG,EAAE,CAAC;IAEf,YAAY,KAAa;QACvB,IAAI,KAAK,GAAG,EAAE,IAAI,KAAK,IAAI,WAAW,EAAE,CAAC;YACvC,MAAM,IAAI,UAAU,CAAC,SAAS,KAAK,mBAAmB,WAAW,IAAI,CAAC,CAAC;QACzE,CAAC;QACD,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;IACtB,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,IAAY;QACrB,IAAI,CAAC,SAAS,EAAE,CAAC;QACjB,IAAI,IAAI,CAAC,SAAS,IAAI,cAAc,EAAE,CAAC;YACrC,MAAM,IAAI,mBAAmB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC7C,CAAC;QACD,OAAO,IAAI,YAAY,CAAC,CAAC,IAAI,CAAC,MAAM,IAAI,aAAa,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC;IAC3E,CAAC;CACF"}
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export { CounterTokenSource } from './counter-token-source.ts';
2
+ export { EpochExhaustedError } from './epoch-exhausted-error.ts';
2
3
  export { EpochTokenSource } from './epoch-token-source.ts';
3
4
  export type { FencedLease } from './fenced-lease.ts';
4
5
  export { FencingToken } from './fencing-token.ts';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,YAAY,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,yBAAyB,EAAE,MAAM,mCAAmC,CAAC;AAC9E,YAAY,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,YAAY,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,yBAAyB,EAAE,MAAM,mCAAmC,CAAC;AAC9E,YAAY,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC"}
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  export { CounterTokenSource } from "./counter-token-source.js";
2
+ export { EpochExhaustedError } from "./epoch-exhausted-error.js";
2
3
  export { EpochTokenSource } from "./epoch-token-source.js";
3
4
  export { FencingToken } from "./fencing-token.js";
4
5
  export { FileTokenSource } from "./file-token-source.js";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAE3D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,yBAAyB,EAAE,MAAM,mCAAmC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAE3D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,yBAAyB,EAAE,MAAM,mCAAmC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zukhruf/fencing",
3
- "version": "0.3.36",
3
+ "version": "0.3.38",
4
4
  "description": "Fencing tokens: a number that grows with each grant, so a protected resource refuses the writes of a stale holder. Token sources that count in memory, in files, or by epoch, and the fenced lease that carries a token.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -40,7 +40,7 @@
40
40
  "access": "public"
41
41
  },
42
42
  "dependencies": {
43
- "@zukhruf/fs": "^0.3.36",
44
- "@zukhruf/lease": "^0.3.36"
43
+ "@zukhruf/fs": "^0.3.38",
44
+ "@zukhruf/lease": "^0.3.38"
45
45
  }
46
46
  }