@mark1russell7/service 0.5.5 → 0.5.6

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.
@@ -12,6 +12,25 @@ const holdLate = (life, hold) => {
12
12
  };
13
13
  /** This function gives the hold of each drain under a lifecycle, as it is at this time. */
14
14
  const lateHolds = (life) => [...holds.get(life) ?? []].map((hold) => hold());
15
+ const owners = /* @__PURE__ */ new WeakMap();
16
+ const outside = /* @__PURE__ */ new WeakMap();
17
+ /** This function records the lifecycle that made a stream, and gives the stream. A stream keeps its first owner. */
18
+ const ownStream = (stream, life) => {
19
+ if (!owners.has(stream)) owners.set(stream, life);
20
+ return stream;
21
+ };
22
+ /** This function gives the lifecycle that made a stream, or null for a stream outside each lifecycle. */
23
+ const ownerOf = (stream) => owners.get(stream) ?? null;
24
+ /** This function adds the count of streams outside a lifecycle that a drain found open at its deadline. */
25
+ const noteOutside = (life, count) => {
26
+ if (count > 0) outside.set(life, (outside.get(life) ?? 0) + count);
27
+ };
28
+ /** This function gives the count of streams outside a lifecycle that its drains found, and sets the count to zero. */
29
+ const takeOutside = (life) => {
30
+ const count = outside.get(life) ?? 0;
31
+ outside.delete(life);
32
+ return count;
33
+ };
15
34
  //#endregion
16
35
  //#region src/knobs.ts
17
36
  /**
@@ -48,6 +67,6 @@ const countOf = (knobs, name, owner) => {
48
67
  return value;
49
68
  };
50
69
  //#endregion
51
- export { lateHolds as a, holdLate as i, countOf as n, millisecondsOf as r, boundedMillisecondsOf as t };
70
+ export { lateHolds as a, ownerOf as c, holdLate as i, takeOutside as l, countOf as n, noteOutside as o, millisecondsOf as r, ownStream as s, boundedMillisecondsOf as t };
52
71
 
53
- //# sourceMappingURL=knobs-BZAsgb5H.js.map
72
+ //# sourceMappingURL=knobs-D2ClI68I.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"knobs-D2ClI68I.js","names":[],"sources":["../src/drains.ts","../src/knobs.ts"],"sourcesContent":["// The holds of the drains after their deadline (SYS-29). A transport that waits after the deadline of\n// its drain gives its hold under its lifecycle. At the cap of the drain, the lifecycle reads each hold.\n// A drain that waits only for the bytes of its answers did its work, thus the phase does not fail.\n\n/** A late hold tells what holds the drain of a transport after its deadline. */\nexport interface LateHold {\n /** This count is the number of calls whose end did not come: their handler still runs. */\n readonly running: number;\n /** This count is the number of answers whose bytes did not go to the client, for example to a client that does not read. */\n readonly unflushed: number;\n}\n\nconst holds = new WeakMap<object, Set<() => LateHold>>();\n\n/** This function adds the hold of a drain under its lifecycle. It gives the function that removes the hold. */\nexport const holdLate = (life: object, hold: () => LateHold): (() => void) => {\n const set = holds.get(life) ?? new Set<() => LateHold>();\n holds.set(life, set);\n set.add(hold);\n return () => {\n set.delete(hold);\n };\n};\n\n/** This function gives the hold of each drain under a lifecycle, as it is at this time. */\nexport const lateHolds = (life: object): LateHold[] => [...(holds.get(life) ?? [])].map((hold) => hold());\n\n// The owner of each stream of a request: the lifecycle whose `life.request` made it. A drain waits only\n// for the streams of its own lifecycle, because only its cut ends them. A stream outside the lifecycle\n// does not hold a drain, as in 0.5.4. The drain only counts it, for the record of the phase.\nconst owners = new WeakMap<object, object>();\nconst outside = new WeakMap<object, number>();\n\n/** This function records the lifecycle that made a stream, and gives the stream. A stream keeps its first owner. */\nexport const ownStream = <T extends object>(stream: T, life: object): T => {\n if (!owners.has(stream)) owners.set(stream, life);\n return stream;\n};\n\n/** This function gives the lifecycle that made a stream, or null for a stream outside each lifecycle. */\nexport const ownerOf = (stream: object): object | null => owners.get(stream) ?? null;\n\n/** This function adds the count of streams outside a lifecycle that a drain found open at its deadline. */\nexport const noteOutside = (life: object, count: number): void => {\n if (count > 0) outside.set(life, (outside.get(life) ?? 0) + count);\n};\n\n/** This function gives the count of streams outside a lifecycle that its drains found, and sets the count to zero. */\nexport const takeOutside = (life: object): number => {\n const count = outside.get(life) ?? 0;\n outside.delete(life);\n return count;\n};\n","import type { Extent } from \"@mark1russell7/quantity\";\nimport { convertible, valueIn } from \"@mark1russell7/quantity\";\n\n/** A knob record is the knobs of a part, by name. A knob that is absent is undefined. */\nexport type KnobRecord = Readonly<Record<string, Extent | undefined>>;\n\n/**\n * This function gives a time knob in milliseconds, or infinity for a time without a bound. The\n * runtime has no defaults, thus a knob that is absent throws. A knob that is not a time, or that is\n * less than zero, also throws.\n */\nexport const millisecondsOf = (knobs: KnobRecord, name: string, owner: string): number => {\n const amount = knobs[name];\n if (amount === undefined) throw new Error(`${owner} needs the knob ${name}: it has no defaults`);\n if (!convertible(amount.unit, \"s\")) throw new Error(`the knob ${name} is not a time`);\n if (amount.value === \"infinite\") return Number.POSITIVE_INFINITY;\n const value = valueIn(amount, \"ms\");\n if (!(value >= 0)) throw new Error(`the knob ${name} is less than zero`);\n return value;\n};\n\n/** This function gives a time knob in milliseconds, and it throws for a time without a bound. */\nexport const boundedMillisecondsOf = (knobs: KnobRecord, name: string, owner: string): number => {\n const value = millisecondsOf(knobs, name, owner);\n if (!Number.isFinite(value)) throw new Error(`the knob ${name} of ${owner} has no bound: it needs a time`);\n return value;\n};\n\n/**\n * This function gives a count knob (the unit `count`) as a whole number above zero, or infinity\n * for a count without a bound. A knob that is absent, not a count, or not a whole number above zero throws.\n */\nexport const countOf = (knobs: KnobRecord, name: string, owner: string): number => {\n const amount = knobs[name];\n if (amount === undefined) throw new Error(`${owner} needs the knob ${name}: it has no defaults`);\n if (!convertible(amount.unit, \"count\")) throw new Error(`the knob ${name} is not a count`);\n if (amount.value === \"infinite\") return Number.POSITIVE_INFINITY;\n const value = valueIn(amount, \"count\");\n if (!(Number.isInteger(value) && value >= 1)) throw new Error(`the knob ${name} is ${value}, not a whole number above zero`);\n return value;\n};\n"],"mappings":";;AAYA,MAAM,wBAAQ,IAAI,QAAqC;;AAGvD,MAAa,YAAY,MAAc,SAAuC;CAC5E,MAAM,MAAM,MAAM,IAAI,IAAI,qBAAK,IAAI,IAAoB;CACvD,MAAM,IAAI,MAAM,GAAG;CACnB,IAAI,IAAI,IAAI;CACZ,aAAa;EACX,IAAI,OAAO,IAAI;CACjB;AACF;;AAGA,MAAa,aAAa,SAA6B,CAAC,GAAI,MAAM,IAAI,IAAI,KAAK,CAAC,CAAE,CAAC,CAAC,KAAK,SAAS,KAAK,CAAC;AAKxG,MAAM,yBAAS,IAAI,QAAwB;AAC3C,MAAM,0BAAU,IAAI,QAAwB;;AAG5C,MAAa,aAA+B,QAAW,SAAoB;CACzE,IAAI,CAAC,OAAO,IAAI,MAAM,GAAG,OAAO,IAAI,QAAQ,IAAI;CAChD,OAAO;AACT;;AAGA,MAAa,WAAW,WAAkC,OAAO,IAAI,MAAM,KAAK;;AAGhF,MAAa,eAAe,MAAc,UAAwB;CAChE,IAAI,QAAQ,GAAG,QAAQ,IAAI,OAAO,QAAQ,IAAI,IAAI,KAAK,KAAK,KAAK;AACnE;;AAGA,MAAa,eAAe,SAAyB;CACnD,MAAM,QAAQ,QAAQ,IAAI,IAAI,KAAK;CACnC,QAAQ,OAAO,IAAI;CACnB,OAAO;AACT;;;;;;;;ACzCA,MAAa,kBAAkB,OAAmB,MAAc,UAA0B;CACxF,MAAM,SAAS,MAAM;CACrB,IAAI,WAAW,KAAA,GAAW,MAAM,IAAI,MAAM,GAAG,MAAM,kBAAkB,KAAK,qBAAqB;CAC/F,IAAI,CAAC,YAAY,OAAO,MAAM,GAAG,GAAG,MAAM,IAAI,MAAM,YAAY,KAAK,eAAe;CACpF,IAAI,OAAO,UAAU,YAAY,OAAO,OAAO;CAC/C,MAAM,QAAQ,QAAQ,QAAQ,IAAI;CAClC,IAAI,EAAE,SAAS,IAAI,MAAM,IAAI,MAAM,YAAY,KAAK,mBAAmB;CACvE,OAAO;AACT;;AAGA,MAAa,yBAAyB,OAAmB,MAAc,UAA0B;CAC/F,MAAM,QAAQ,eAAe,OAAO,MAAM,KAAK;CAC/C,IAAI,CAAC,OAAO,SAAS,KAAK,GAAG,MAAM,IAAI,MAAM,YAAY,KAAK,MAAM,MAAM,+BAA+B;CACzG,OAAO;AACT;;;;;AAMA,MAAa,WAAW,OAAmB,MAAc,UAA0B;CACjF,MAAM,SAAS,MAAM;CACrB,IAAI,WAAW,KAAA,GAAW,MAAM,IAAI,MAAM,GAAG,MAAM,kBAAkB,KAAK,qBAAqB;CAC/F,IAAI,CAAC,YAAY,OAAO,MAAM,OAAO,GAAG,MAAM,IAAI,MAAM,YAAY,KAAK,gBAAgB;CACzF,IAAI,OAAO,UAAU,YAAY,OAAO,OAAO;CAC/C,MAAM,QAAQ,QAAQ,QAAQ,OAAO;CACrC,IAAI,EAAE,OAAO,UAAU,KAAK,KAAK,SAAS,IAAI,MAAM,IAAI,MAAM,YAAY,KAAK,MAAM,MAAM,gCAAgC;CAC3H,OAAO;AACT"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package",
3
3
  "name": "@mark1russell7/service",
4
- "version": "0.5.5",
4
+ "version": "0.5.6",
5
5
  "description": "A service declared as data before it starts, and its runtime: checks on jittered loops, a latch for each policy, probes from the cache, the startup in its sequence, and a staged, capped drain. The timer-ordering law checks the declaration. Its clock, heartbeat and backoff also work alone, in a browser too.",
6
6
  "keywords": [
7
7
  "service",
@@ -1 +0,0 @@
1
- {"version":3,"file":"knobs-BZAsgb5H.js","names":[],"sources":["../src/drains.ts","../src/knobs.ts"],"sourcesContent":["// The holds of the drains after their deadline (SYS-29). A transport that waits after the deadline of\n// its drain gives its hold under its lifecycle. At the cap of the drain, the lifecycle reads each hold.\n// A drain that waits only for the bytes of its answers did its work, thus the phase does not fail.\n\n/** A late hold tells what holds the drain of a transport after its deadline. */\nexport interface LateHold {\n /** This count is the number of calls whose end did not come: their handler still runs. */\n readonly running: number;\n /** This count is the number of answers whose bytes did not go to the client, for example to a client that does not read. */\n readonly unflushed: number;\n}\n\nconst holds = new WeakMap<object, Set<() => LateHold>>();\n\n/** This function adds the hold of a drain under its lifecycle. It gives the function that removes the hold. */\nexport const holdLate = (life: object, hold: () => LateHold): (() => void) => {\n const set = holds.get(life) ?? new Set<() => LateHold>();\n holds.set(life, set);\n set.add(hold);\n return () => {\n set.delete(hold);\n };\n};\n\n/** This function gives the hold of each drain under a lifecycle, as it is at this time. */\nexport const lateHolds = (life: object): LateHold[] => [...(holds.get(life) ?? [])].map((hold) => hold());\n","import type { Extent } from \"@mark1russell7/quantity\";\nimport { convertible, valueIn } from \"@mark1russell7/quantity\";\n\n/** A knob record is the knobs of a part, by name. A knob that is absent is undefined. */\nexport type KnobRecord = Readonly<Record<string, Extent | undefined>>;\n\n/**\n * This function gives a time knob in milliseconds, or infinity for a time without a bound. The\n * runtime has no defaults, thus a knob that is absent throws. A knob that is not a time, or that is\n * less than zero, also throws.\n */\nexport const millisecondsOf = (knobs: KnobRecord, name: string, owner: string): number => {\n const amount = knobs[name];\n if (amount === undefined) throw new Error(`${owner} needs the knob ${name}: it has no defaults`);\n if (!convertible(amount.unit, \"s\")) throw new Error(`the knob ${name} is not a time`);\n if (amount.value === \"infinite\") return Number.POSITIVE_INFINITY;\n const value = valueIn(amount, \"ms\");\n if (!(value >= 0)) throw new Error(`the knob ${name} is less than zero`);\n return value;\n};\n\n/** This function gives a time knob in milliseconds, and it throws for a time without a bound. */\nexport const boundedMillisecondsOf = (knobs: KnobRecord, name: string, owner: string): number => {\n const value = millisecondsOf(knobs, name, owner);\n if (!Number.isFinite(value)) throw new Error(`the knob ${name} of ${owner} has no bound: it needs a time`);\n return value;\n};\n\n/**\n * This function gives a count knob (the unit `count`) as a whole number above zero, or infinity\n * for a count without a bound. A knob that is absent, not a count, or not a whole number above zero throws.\n */\nexport const countOf = (knobs: KnobRecord, name: string, owner: string): number => {\n const amount = knobs[name];\n if (amount === undefined) throw new Error(`${owner} needs the knob ${name}: it has no defaults`);\n if (!convertible(amount.unit, \"count\")) throw new Error(`the knob ${name} is not a count`);\n if (amount.value === \"infinite\") return Number.POSITIVE_INFINITY;\n const value = valueIn(amount, \"count\");\n if (!(Number.isInteger(value) && value >= 1)) throw new Error(`the knob ${name} is ${value}, not a whole number above zero`);\n return value;\n};\n"],"mappings":";;AAYA,MAAM,wBAAQ,IAAI,QAAqC;;AAGvD,MAAa,YAAY,MAAc,SAAuC;CAC5E,MAAM,MAAM,MAAM,IAAI,IAAI,qBAAK,IAAI,IAAoB;CACvD,MAAM,IAAI,MAAM,GAAG;CACnB,IAAI,IAAI,IAAI;CACZ,aAAa;EACX,IAAI,OAAO,IAAI;CACjB;AACF;;AAGA,MAAa,aAAa,SAA6B,CAAC,GAAI,MAAM,IAAI,IAAI,KAAK,CAAC,CAAE,CAAC,CAAC,KAAK,SAAS,KAAK,CAAC;;;;;;;;ACdxG,MAAa,kBAAkB,OAAmB,MAAc,UAA0B;CACxF,MAAM,SAAS,MAAM;CACrB,IAAI,WAAW,KAAA,GAAW,MAAM,IAAI,MAAM,GAAG,MAAM,kBAAkB,KAAK,qBAAqB;CAC/F,IAAI,CAAC,YAAY,OAAO,MAAM,GAAG,GAAG,MAAM,IAAI,MAAM,YAAY,KAAK,eAAe;CACpF,IAAI,OAAO,UAAU,YAAY,OAAO,OAAO;CAC/C,MAAM,QAAQ,QAAQ,QAAQ,IAAI;CAClC,IAAI,EAAE,SAAS,IAAI,MAAM,IAAI,MAAM,YAAY,KAAK,mBAAmB;CACvE,OAAO;AACT;;AAGA,MAAa,yBAAyB,OAAmB,MAAc,UAA0B;CAC/F,MAAM,QAAQ,eAAe,OAAO,MAAM,KAAK;CAC/C,IAAI,CAAC,OAAO,SAAS,KAAK,GAAG,MAAM,IAAI,MAAM,YAAY,KAAK,MAAM,MAAM,+BAA+B;CACzG,OAAO;AACT;;;;;AAMA,MAAa,WAAW,OAAmB,MAAc,UAA0B;CACjF,MAAM,SAAS,MAAM;CACrB,IAAI,WAAW,KAAA,GAAW,MAAM,IAAI,MAAM,GAAG,MAAM,kBAAkB,KAAK,qBAAqB;CAC/F,IAAI,CAAC,YAAY,OAAO,MAAM,OAAO,GAAG,MAAM,IAAI,MAAM,YAAY,KAAK,gBAAgB;CACzF,IAAI,OAAO,UAAU,YAAY,OAAO,OAAO;CAC/C,MAAM,QAAQ,QAAQ,QAAQ,OAAO;CACrC,IAAI,EAAE,OAAO,UAAU,KAAK,KAAK,SAAS,IAAI,MAAM,IAAI,MAAM,YAAY,KAAK,MAAM,MAAM,gCAAgC;CAC3H,OAAO;AACT"}