@procedures/systems 0.0.0-stage → 0.2.3

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.
Files changed (44) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +59 -2
  3. package/dist/.tsbuildinfo +1 -0
  4. package/dist/index.d.ts +7 -0
  5. package/dist/index.d.ts.map +1 -0
  6. package/dist/index.js +7 -0
  7. package/dist/index.js.map +1 -0
  8. package/dist/lint.d.ts +61 -0
  9. package/dist/lint.d.ts.map +1 -0
  10. package/dist/lint.js +84 -0
  11. package/dist/lint.js.map +1 -0
  12. package/dist/module.d.ts +14 -0
  13. package/dist/module.d.ts.map +1 -0
  14. package/dist/module.js +86 -0
  15. package/dist/module.js.map +1 -0
  16. package/dist/procedures/systems/index.d.ts +2 -0
  17. package/dist/procedures/systems/index.d.ts.map +1 -0
  18. package/dist/procedures/systems/index.js +2 -0
  19. package/dist/procedures/systems/index.js.map +1 -0
  20. package/dist/procedures/systems/timers.d.ts +16 -0
  21. package/dist/procedures/systems/timers.d.ts.map +1 -0
  22. package/dist/procedures/systems/timers.js +47 -0
  23. package/dist/procedures/systems/timers.js.map +1 -0
  24. package/dist/register.d.ts +6 -0
  25. package/dist/register.d.ts.map +1 -0
  26. package/dist/register.js +8 -0
  27. package/dist/register.js.map +1 -0
  28. package/dist/rules.d.ts +10 -0
  29. package/dist/rules.d.ts.map +1 -0
  30. package/dist/rules.js +51 -0
  31. package/dist/rules.js.map +1 -0
  32. package/dist/types.d.ts +52 -0
  33. package/dist/types.d.ts.map +1 -0
  34. package/dist/types.js +8 -0
  35. package/dist/types.js.map +1 -0
  36. package/package.json +78 -3
  37. package/src/index.ts +7 -0
  38. package/src/lint.ts +129 -0
  39. package/src/module.ts +98 -0
  40. package/src/procedures/systems/index.ts +1 -0
  41. package/src/procedures/systems/timers.ts +51 -0
  42. package/src/register.ts +10 -0
  43. package/src/rules.ts +54 -0
  44. package/src/types.ts +51 -0
package/dist/lint.js ADDED
@@ -0,0 +1,84 @@
1
+ /**
2
+ * The timer law for the client (roadmap R34): the settings of an application, the values of the
3
+ * symbols of the law, and the verdict of each rule.
4
+ *
5
+ * A setting that the application does not give takes the default of the core (`TIMER_DEFAULTS`
6
+ * of `@procedures/client`). A timer that is off by default (the per-try timeout, the overall
7
+ * timeout) has no value: a rule that reads it gives the verdict "depends".
8
+ */
9
+ import { TIMER_DEFAULTS, optionalMs } from "@procedures/client";
10
+ import { evaluate, symbolsOf, verdictOf } from "@mark1russell7/service";
11
+ import { CLIENT_RULES } from "./rules.js";
12
+ const seconds = (milliseconds) => milliseconds / 1000;
13
+ /** This function gives the longest backoffs of the retry, in milliseconds, one for each retry. */
14
+ function backoffs(maxRetries, delayMs, multiplier, maxDelayMs) {
15
+ return Array.from({ length: maxRetries }, (_, attempt) => Math.min(maxDelayMs, delayMs * Math.pow(multiplier, attempt)));
16
+ }
17
+ /**
18
+ * This function gives the values of the symbols of the law, in seconds, from the settings and
19
+ * the defaults of the core. It also gives the derived symbols:
20
+ *
21
+ * - `retry_budget@client`: each try at its longest, and each backoff at its longest.
22
+ * - `call_time@client`: the longest call. It is the overall time, or the retry budget when it is shorter.
23
+ * - `heartbeat_detection@client` and `@server`: the time until a side finds a dead connection.
24
+ */
25
+ export function bindingOf(settings = {}) {
26
+ const defaults = TIMER_DEFAULTS;
27
+ const retry = settings.retry ?? {};
28
+ const maxRetries = retry.maxRetries ?? defaults.retry.maxRetries;
29
+ const delayMs = optionalMs(retry.retryDelay, "retry.retryDelay") ?? defaults.retry.retryDelayMs;
30
+ const multiplier = retry.backoffMultiplier ?? defaults.retry.backoffMultiplier;
31
+ const maxDelayMs = optionalMs(retry.maxDelay, "retry.maxDelay") ?? defaults.retry.maxDelayMs;
32
+ const client = settings.webSocketClient ?? {};
33
+ const server = settings.webSocketServer ?? {};
34
+ const requestMs = optionalMs(client.requestTimeout, "webSocketClient.requestTimeout") ?? defaults.webSocketClient.requestTimeoutMs;
35
+ const perAttemptMs = optionalMs(settings.perAttempt, "perAttempt");
36
+ const overallMs = optionalMs(settings.overall, "overall");
37
+ // A try ends at the per-try timeout, or at the request time of the transport
38
+ const tryMs = perAttemptMs === undefined ? requestMs : Math.min(perAttemptMs, requestMs);
39
+ const waits = backoffs(maxRetries, delayMs, multiplier, maxDelayMs);
40
+ const budgetMs = (maxRetries + 1) * tryMs + waits.reduce((sum, wait) => sum + wait, 0);
41
+ const callMs = overallMs === undefined ? budgetMs : Math.min(overallMs, budgetMs);
42
+ const clientDetectionMs = (optionalMs(client.heartbeatInterval, "webSocketClient.heartbeatInterval") ?? defaults.webSocketClient.heartbeatIntervalMs) *
43
+ (client.heartbeatMisses ?? defaults.webSocketClient.heartbeatMisses) +
44
+ (optionalMs(client.heartbeatTimeout, "webSocketClient.heartbeatTimeout") ?? defaults.webSocketClient.heartbeatTimeoutMs);
45
+ const serverDetectionMs = (optionalMs(server.heartbeatInterval, "webSocketServer.heartbeatInterval") ?? defaults.webSocketServer.heartbeatIntervalMs) *
46
+ (server.heartbeatMisses ?? defaults.webSocketServer.heartbeatMisses);
47
+ const bind = {
48
+ "transport_request_timeout@client": seconds(requestMs),
49
+ "retry_budget@client": seconds(budgetMs),
50
+ "call_time@client": seconds(callMs),
51
+ "max_backoff@client": waits.length === 0 ? 0 : seconds(Math.max(...waits)),
52
+ "breaker_reset@client": seconds(optionalMs(settings.circuitBreaker?.resetTimeout, "circuitBreaker.resetTimeout") ?? defaults.circuitBreaker.resetTimeoutMs),
53
+ "heartbeat_detection@client": seconds(clientDetectionMs),
54
+ "heartbeat_detection@server": seconds(serverDetectionMs),
55
+ "reverse_request_timeout@server": seconds(optionalMs(server.reverseRequestTimeout, "webSocketServer.reverseRequestTimeout") ?? defaults.webSocketServer.reverseRequestTimeoutMs),
56
+ "idempotency_ttl@server": seconds(optionalMs(settings.idempotencyTtl, "idempotencyTtl") ?? defaults.idempotency.ttlMs),
57
+ };
58
+ // A timer that is off has no value: its rules give "depends"
59
+ if (perAttemptMs !== undefined)
60
+ bind["try_timeout@client"] = seconds(perAttemptMs);
61
+ if (overallMs !== undefined)
62
+ bind["overall_timeout@client"] = seconds(overallMs);
63
+ // A retry without a limit of its backoff: the law reads Infinity as "inf"
64
+ for (const [key, value] of Object.entries(bind))
65
+ if (value === Number.POSITIVE_INFINITY)
66
+ bind[key] = "inf";
67
+ return bind;
68
+ }
69
+ /** This function gives the verdict of each rule for the settings of an application. */
70
+ export function lintTimers(settings = {}, rules = CLIENT_RULES) {
71
+ const bind = bindingOf(settings);
72
+ return rules.map((rule) => {
73
+ const evaluated = evaluate(rule, bind);
74
+ return {
75
+ rule: rule.id,
76
+ verdict: verdictOf(rule, bind, evaluated),
77
+ statement: rule.rule,
78
+ ...(rule.window !== undefined ? { window: rule.window } : {}),
79
+ evaluated,
80
+ unbound: symbolsOf(rule).filter((symbol) => bind[symbol] === undefined),
81
+ };
82
+ });
83
+ }
84
+ //# sourceMappingURL=lint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lint.js","sourceRoot":"","sources":["../src/lint.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * The procedures of @procedures/systems as data. Importing this file registers nothing.
3
+ *
4
+ * Scaffold a procedure with: mark procedure new <name> --path packages/systems
5
+ */
6
+ import { type ProcedureModule, type ProcedureRegistry } from "@procedures/client";
7
+ export declare const systemsModule: ProcedureModule;
8
+ export default systemsModule;
9
+ /**
10
+ * This function registers the procedures of @procedures/systems in a registry. The default is the
11
+ * global registry.
12
+ */
13
+ export declare function registerSystemsProcedures(registry?: ProcedureRegistry): void;
14
+ //# sourceMappingURL=module.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../src/module.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAmE,KAAK,eAAe,EAAE,KAAK,iBAAiB,EAA+B,MAAM,oBAAoB,CAAC;AAgFhL,eAAO,MAAM,aAAa,EAAE,eAA+E,CAAC;eAE7F,aAAa;AAE5B;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,QAAQ,GAAE,iBAAsC,GAAG,IAAI,CAEhG"}
package/dist/module.js ADDED
@@ -0,0 +1,86 @@
1
+ /**
2
+ * The procedures of @procedures/systems as data. Importing this file registers nothing.
3
+ *
4
+ * Scaffold a procedure with: mark procedure new <name> --path packages/systems
5
+ */
6
+ import { z } from "zod";
7
+ import { defineModule, registerModules, PROCEDURE_REGISTRY, PURE_EFFECTS, createProcedure, zodAdapter } from "@procedures/client";
8
+ import { systemsTimers } from "./procedures/systems/timers.js";
9
+ /** A time in milliseconds: the wire carries times in milliseconds (roadmap R11). */
10
+ const milliseconds = (description) => z.number().min(0).optional().describe(`${description}, in milliseconds`);
11
+ const SystemsTimersInputSchema = z.object({
12
+ perAttemptMs: milliseconds("The time of one try (resilience perAttempt)"),
13
+ overallMs: milliseconds("The time of a call with its retries (resilience overall)"),
14
+ retry: z
15
+ .object({
16
+ maxRetries: z.number().int().min(0).optional().describe("The tries after the first one"),
17
+ retryDelayMs: milliseconds("The first backoff"),
18
+ backoffMultiplier: z.number().min(1).optional().describe("The factor of each next backoff"),
19
+ maxDelayMs: milliseconds("The longest backoff"),
20
+ })
21
+ .optional()
22
+ .describe("The settings of the retry"),
23
+ circuitBreaker: z.object({ resetTimeoutMs: milliseconds("The time that the breaker stays open") }).optional().describe("The settings of the circuit breaker"),
24
+ webSocketClient: z
25
+ .object({
26
+ requestTimeoutMs: milliseconds("The time until the first frame of a call"),
27
+ heartbeatIntervalMs: milliseconds("The time between two pings"),
28
+ heartbeatTimeoutMs: milliseconds("The time that the client waits for a pong"),
29
+ heartbeatMisses: z.number().int().min(1).optional().describe("The pongs that can go missing before the connection closes"),
30
+ })
31
+ .optional()
32
+ .describe("The settings of the WebSocket client"),
33
+ webSocketServer: z
34
+ .object({
35
+ heartbeatIntervalMs: milliseconds("The time between two pings of the server"),
36
+ heartbeatMisses: z.number().int().min(1).optional().describe("The pongs that can go missing before the server closes the connection"),
37
+ reverseRequestTimeoutMs: milliseconds("The time until the first frame of a call of the server to a client"),
38
+ })
39
+ .optional()
40
+ .describe("The settings of the WebSocket server"),
41
+ idempotencyTtlMs: milliseconds("The time that the server keeps the result of a keyed write"),
42
+ });
43
+ const SystemsTimersOutputSchema = z.object({
44
+ ok: z.boolean().describe("True when no rule is violated"),
45
+ findings: z
46
+ .array(z.object({
47
+ rule: z.string().describe("The id of the rule"),
48
+ verdict: z.enum(["holds", "violated", "unbounded", "depends"]).describe("The verdict of the rule"),
49
+ statement: z.string().describe("The rule in words"),
50
+ window: z.string().optional().describe("What goes wrong when the rule is violated"),
51
+ evaluated: z
52
+ .array(z.object({
53
+ lhs: z.number().nullable().describe("The left side, in seconds"),
54
+ rhs: z.number().nullable().describe("The right side, in seconds"),
55
+ margin: z.number().describe("The margin, in seconds"),
56
+ holds: z.boolean().nullable().describe("True when the inequality holds. Null: a symbol has no value."),
57
+ }))
58
+ .describe("Each inequality of the rule"),
59
+ unbound: z.array(z.string()).describe("The symbols without a value"),
60
+ }))
61
+ .describe("The verdict of each rule"),
62
+ });
63
+ const systemsTimersProcedure = createProcedure()
64
+ .path(["systems", "timers"])
65
+ .input(zodAdapter(SystemsTimersInputSchema))
66
+ .output(zodAdapter(SystemsTimersOutputSchema))
67
+ .meta({
68
+ description: "The verdicts of the timer law for the timer settings of an application",
69
+ args: [],
70
+ shorts: {},
71
+ output: "json",
72
+ // It reads only its input, and changes nothing
73
+ effects: PURE_EFFECTS,
74
+ })
75
+ .handler(async (input) => systemsTimers(input))
76
+ .build();
77
+ export const systemsModule = defineModule("@procedures/systems", [systemsTimersProcedure]);
78
+ export default systemsModule;
79
+ /**
80
+ * This function registers the procedures of @procedures/systems in a registry. The default is the
81
+ * global registry.
82
+ */
83
+ export function registerSystemsProcedures(registry = PROCEDURE_REGISTRY) {
84
+ registerModules(registry, [systemsModule]);
85
+ }
86
+ //# sourceMappingURL=module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"module.js","sourceRoot":"","sources":["../src/module.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export { systemsTimers } from "./timers.js";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/procedures/systems/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { systemsTimers } from "./timers.js";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/procedures/systems/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * systems.timers procedure
3
+ *
4
+ * The verdicts of the timer law for the timer settings of an application (roadmap R34). The
5
+ * input gives the times in milliseconds, as the wire does. A time that the input does not give
6
+ * takes the default of the core.
7
+ */
8
+ import { type TimerSettings } from "../../lint.js";
9
+ import type { SystemsTimersInput, SystemsTimersOutput } from "../../types.js";
10
+ /** This function gives the settings of `lintTimers()` from the input of the procedure. */
11
+ export declare function settingsOf(input: SystemsTimersInput): TimerSettings;
12
+ /**
13
+ * The verdicts of the timer law for the timer settings of an application
14
+ */
15
+ export declare function systemsTimers(input: SystemsTimersInput): Promise<SystemsTimersOutput>;
16
+ //# sourceMappingURL=timers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timers.d.ts","sourceRoot":"","sources":["../../../src/procedures/systems/timers.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAc,KAAK,aAAa,EAAE,MAAM,eAAe,CAAC;AAC/D,OAAO,KAAK,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAI9E,0FAA0F;AAC1F,wBAAgB,UAAU,CAAC,KAAK,EAAE,kBAAkB,GAAG,aAAa,CAwBnE;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAM3F"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * systems.timers procedure
3
+ *
4
+ * The verdicts of the timer law for the timer settings of an application (roadmap R34). The
5
+ * input gives the times in milliseconds, as the wire does. A time that the input does not give
6
+ * takes the default of the core.
7
+ */
8
+ import { ms } from "@procedures/client";
9
+ import { lintTimers } from "../../lint.js";
10
+ const duration = (milliseconds) => (milliseconds === undefined ? undefined : ms(milliseconds));
11
+ /** This function gives the settings of `lintTimers()` from the input of the procedure. */
12
+ export function settingsOf(input) {
13
+ return {
14
+ perAttempt: duration(input.perAttemptMs),
15
+ overall: duration(input.overallMs),
16
+ retry: input.retry && {
17
+ maxRetries: input.retry.maxRetries,
18
+ retryDelay: duration(input.retry.retryDelayMs),
19
+ backoffMultiplier: input.retry.backoffMultiplier,
20
+ maxDelay: duration(input.retry.maxDelayMs),
21
+ },
22
+ circuitBreaker: input.circuitBreaker && { resetTimeout: duration(input.circuitBreaker.resetTimeoutMs) },
23
+ webSocketClient: input.webSocketClient && {
24
+ requestTimeout: duration(input.webSocketClient.requestTimeoutMs),
25
+ heartbeatInterval: duration(input.webSocketClient.heartbeatIntervalMs),
26
+ heartbeatTimeout: duration(input.webSocketClient.heartbeatTimeoutMs),
27
+ heartbeatMisses: input.webSocketClient.heartbeatMisses,
28
+ },
29
+ webSocketServer: input.webSocketServer && {
30
+ heartbeatInterval: duration(input.webSocketServer.heartbeatIntervalMs),
31
+ heartbeatMisses: input.webSocketServer.heartbeatMisses,
32
+ reverseRequestTimeout: duration(input.webSocketServer.reverseRequestTimeoutMs),
33
+ },
34
+ idempotencyTtl: duration(input.idempotencyTtlMs),
35
+ };
36
+ }
37
+ /**
38
+ * The verdicts of the timer law for the timer settings of an application
39
+ */
40
+ export async function systemsTimers(input) {
41
+ const findings = lintTimers(settingsOf(input));
42
+ return {
43
+ ok: findings.every((finding) => finding.verdict !== "violated"),
44
+ findings: findings.map((finding) => ({ ...finding, evaluated: [...finding.evaluated], unbound: [...finding.unbound] })),
45
+ };
46
+ }
47
+ //# sourceMappingURL=timers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timers.js","sourceRoot":"","sources":["../../../src/procedures/systems/timers.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,EAAE,EAAiB,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,UAAU,EAAsB,MAAM,eAAe,CAAC;AAG/D,MAAM,QAAQ,GAAG,CAAC,YAAgC,EAAwB,EAAE,CAAC,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;AAEzI,0FAA0F;AAC1F,MAAM,UAAU,UAAU,CAAC,KAAyB;IAClD,OAAO;QACL,UAAU,EAAE,QAAQ,CAAC,KAAK,CAAC,YAAY,CAAC;QACxC,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,SAAS,CAAC;QAClC,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI;YACpB,UAAU,EAAE,KAAK,CAAC,KAAK,CAAC,UAAU;YAClC,UAAU,EAAE,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,YAAY,CAAC;YAC9C,iBAAiB,EAAE,KAAK,CAAC,KAAK,CAAC,iBAAiB;YAChD,QAAQ,EAAE,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC;SAC3C;QACD,cAAc,EAAE,KAAK,CAAC,cAAc,IAAI,EAAE,YAAY,EAAE,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE;QACvG,eAAe,EAAE,KAAK,CAAC,eAAe,IAAI;YACxC,cAAc,EAAE,QAAQ,CAAC,KAAK,CAAC,eAAe,CAAC,gBAAgB,CAAC;YAChE,iBAAiB,EAAE,QAAQ,CAAC,KAAK,CAAC,eAAe,CAAC,mBAAmB,CAAC;YACtE,gBAAgB,EAAE,QAAQ,CAAC,KAAK,CAAC,eAAe,CAAC,kBAAkB,CAAC;YACpE,eAAe,EAAE,KAAK,CAAC,eAAe,CAAC,eAAe;SACvD;QACD,eAAe,EAAE,KAAK,CAAC,eAAe,IAAI;YACxC,iBAAiB,EAAE,QAAQ,CAAC,KAAK,CAAC,eAAe,CAAC,mBAAmB,CAAC;YACtE,eAAe,EAAE,KAAK,CAAC,eAAe,CAAC,eAAe;YACtD,qBAAqB,EAAE,QAAQ,CAAC,KAAK,CAAC,eAAe,CAAC,uBAAuB,CAAC;SAC/E;QACD,cAAc,EAAE,QAAQ,CAAC,KAAK,CAAC,gBAAgB,CAAC;KACjD,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,KAAyB;IAC3D,MAAM,QAAQ,GAAG,UAAU,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;IAC/C,OAAO;QACL,EAAE,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,KAAK,UAAU,CAAC;QAC/D,QAAQ,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,OAAO,EAAE,SAAS,EAAE,CAAC,GAAG,OAAO,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;KACxH,CAAC;AACJ,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Importing this file registers the procedures of @procedures/systems in the global registry:
3
+ * `import "@procedures/systems/register"`. The package root registers nothing.
4
+ */
5
+ export * from "./module.js";
6
+ //# sourceMappingURL=register.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../src/register.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,cAAc,aAAa,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Importing this file registers the procedures of @procedures/systems in the global registry:
3
+ * `import "@procedures/systems/register"`. The package root registers nothing.
4
+ */
5
+ import { registerSystemsProcedures } from "./module.js";
6
+ export * from "./module.js";
7
+ registerSystemsProcedures();
8
+ //# sourceMappingURL=register.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register.js","sourceRoot":"","sources":["../src/register.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAExD,cAAc,aAAa,CAAC;AAE5B,yBAAyB,EAAE,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * The rules of the timer law for the client (roadmap R34), as data in the format of
3
+ * `@mark1russell7/service`. Each rule is one or more linear inequalities over symbols at a hop
4
+ * (`try_timeout@client`). `bindingOf()` gives the values of the symbols from the settings of an
5
+ * application.
6
+ */
7
+ import type { Rule } from "@mark1russell7/service";
8
+ /** The rules of the client. */
9
+ export declare const CLIENT_RULES: readonly Rule[];
10
+ //# sourceMappingURL=rules.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../src/rules.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAQnD,+BAA+B;AAC/B,eAAO,MAAM,YAAY,EAAE,SAAS,IAAI,EAqCrB,CAAC"}
package/dist/rules.js ADDED
@@ -0,0 +1,51 @@
1
+ /**
2
+ * The rules of the timer law for the client (roadmap R34), as data in the format of
3
+ * `@mark1russell7/service`. Each rule is one or more linear inequalities over symbols at a hop
4
+ * (`try_timeout@client`). `bindingOf()` gives the values of the symbols from the settings of an
5
+ * application.
6
+ */
7
+ /** A term of one symbol with the coefficient 1. */
8
+ const at = (symbol) => {
9
+ const [knob, hop] = symbol.split("@");
10
+ return { knob: knob, coef: 1, at: hop };
11
+ };
12
+ /** The rules of the client. */
13
+ export const CLIENT_RULES = Object.freeze([
14
+ {
15
+ id: "try-under-transport-timeout",
16
+ rule: "The time of one try is less than the request time of the WebSocket transport.",
17
+ window: "The transport ends the try with its own timeout first. Then the retry sees a transport error, not a TIMEOUT of the try.",
18
+ expr: { lhs: { terms: [at("try_timeout@client")] }, op: "<", rhs: { terms: [at("transport_request_timeout@client")] } },
19
+ },
20
+ {
21
+ id: "overall-covers-retries",
22
+ rule: "The overall time of a call covers each try and each backoff of the retry.",
23
+ window: "The overall timeout ends the call during a backoff or a try, so the last tries never start.",
24
+ expr: { lhs: { terms: [at("overall_timeout@client")] }, op: ">=", rhs: { terms: [at("retry_budget@client")] } },
25
+ },
26
+ {
27
+ id: "keyed-result-outlives-call",
28
+ rule: "The server keeps the result of a keyed write longer than the longest call with its retries.",
29
+ window: "A retry of a keyed write after the end of the time to live runs the write a second time.",
30
+ expr: { lhs: { terms: [at("idempotency_ttl@server")] }, op: ">", rhs: { terms: [at("call_time@client")] } },
31
+ },
32
+ {
33
+ id: "dead-connection-before-request-timeout",
34
+ rule: "The client finds a dead connection before a call on it reaches the request time of the transport.",
35
+ window: "A call on a dead connection fails with a timeout, and the reconnect starts late.",
36
+ expr: { lhs: { terms: [at("heartbeat_detection@client")] }, op: "<", rhs: { terms: [at("transport_request_timeout@client")] } },
37
+ },
38
+ {
39
+ id: "server-finds-dead-client",
40
+ rule: "The server finds a dead client before a call of the server to it reaches its request time.",
41
+ window: "A call of the server to a dead client fails with a timeout, and the server keeps the connection until then.",
42
+ expr: { lhs: { terms: [at("heartbeat_detection@server")] }, op: "<=", rhs: { terms: [at("reverse_request_timeout@server")] } },
43
+ },
44
+ {
45
+ id: "breaker-outlasts-backoff",
46
+ rule: "The circuit breaker stays open longer than the longest backoff of the retry.",
47
+ window: "The retry tries again before the breaker allows a probe, and each try fails at once with the error of the open breaker.",
48
+ expr: { lhs: { terms: [at("breaker_reset@client")] }, op: ">=", rhs: { terms: [at("max_backoff@client")] } },
49
+ },
50
+ ]);
51
+ //# sourceMappingURL=rules.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rules.js","sourceRoot":"","sources":["../src/rules.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,mDAAmD;AACnD,MAAM,EAAE,GAAG,CAAC,MAAc,EAAE,EAAE;IAC5B,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACtC,OAAO,EAAE,IAAI,EAAE,IAAK,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC;AAC3C,CAAC,CAAC;AAEF,+BAA+B;AAC/B,MAAM,CAAC,MAAM,YAAY,GAAoB,MAAM,CAAC,MAAM,CAAC;IACzD;QACE,EAAE,EAAE,6BAA6B;QACjC,IAAI,EAAE,+EAA+E;QACrF,MAAM,EAAE,yHAAyH;QACjI,IAAI,EAAE,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,oBAAoB,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,kCAAkC,CAAC,CAAC,EAAE,EAAE;KACxH;IACD;QACE,EAAE,EAAE,wBAAwB;QAC5B,IAAI,EAAE,2EAA2E;QACjF,MAAM,EAAE,6FAA6F;QACrG,IAAI,EAAE,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,wBAAwB,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,qBAAqB,CAAC,CAAC,EAAE,EAAE;KAChH;IACD;QACE,EAAE,EAAE,4BAA4B;QAChC,IAAI,EAAE,6FAA6F;QACnG,MAAM,EAAE,0FAA0F;QAClG,IAAI,EAAE,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,wBAAwB,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,kBAAkB,CAAC,CAAC,EAAE,EAAE;KAC5G;IACD;QACE,EAAE,EAAE,wCAAwC;QAC5C,IAAI,EAAE,mGAAmG;QACzG,MAAM,EAAE,kFAAkF;QAC1F,IAAI,EAAE,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,4BAA4B,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,kCAAkC,CAAC,CAAC,EAAE,EAAE;KAChI;IACD;QACE,EAAE,EAAE,0BAA0B;QAC9B,IAAI,EAAE,4FAA4F;QAClG,MAAM,EAAE,6GAA6G;QACrH,IAAI,EAAE,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,4BAA4B,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,gCAAgC,CAAC,CAAC,EAAE,EAAE;KAC/H;IACD;QACE,EAAE,EAAE,0BAA0B;QAC9B,IAAI,EAAE,8EAA8E;QACpF,MAAM,EAAE,yHAAyH;QACjI,IAAI,EAAE,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,sBAAsB,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,oBAAoB,CAAC,CAAC,EAAE,EAAE;KAC7G;CACe,CAAC,CAAC"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Type definitions of the procedures of this package
3
+ *
4
+ * mark procedure new adds the types of each new procedure here. The zod schemas are in
5
+ * `module.ts`: an exported schema needs a written type (isolatedDeclarations).
6
+ */
7
+ import type { Verdict } from "@mark1russell7/service";
8
+ /** The timer settings of an application, in milliseconds, as the wire carries times (roadmap R11). */
9
+ export interface SystemsTimersInput {
10
+ perAttemptMs?: number | undefined;
11
+ overallMs?: number | undefined;
12
+ retry?: {
13
+ maxRetries?: number | undefined;
14
+ retryDelayMs?: number | undefined;
15
+ backoffMultiplier?: number | undefined;
16
+ maxDelayMs?: number | undefined;
17
+ } | undefined;
18
+ circuitBreaker?: {
19
+ resetTimeoutMs?: number | undefined;
20
+ } | undefined;
21
+ webSocketClient?: {
22
+ requestTimeoutMs?: number | undefined;
23
+ heartbeatIntervalMs?: number | undefined;
24
+ heartbeatTimeoutMs?: number | undefined;
25
+ heartbeatMisses?: number | undefined;
26
+ } | undefined;
27
+ webSocketServer?: {
28
+ heartbeatIntervalMs?: number | undefined;
29
+ heartbeatMisses?: number | undefined;
30
+ reverseRequestTimeoutMs?: number | undefined;
31
+ } | undefined;
32
+ idempotencyTtlMs?: number | undefined;
33
+ }
34
+ /** The verdict of each rule. */
35
+ export interface SystemsTimersOutput {
36
+ /** True when no rule is violated. */
37
+ ok: boolean;
38
+ findings: Array<{
39
+ rule: string;
40
+ verdict: Verdict;
41
+ statement: string;
42
+ window?: string | undefined;
43
+ evaluated: Array<{
44
+ lhs: number | null;
45
+ rhs: number | null;
46
+ margin: number;
47
+ holds: boolean | null;
48
+ }>;
49
+ unbound: string[];
50
+ }>;
51
+ }
52
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAMtD,sGAAsG;AACtG,MAAM,WAAW,kBAAkB;IACjC,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,KAAK,CAAC,EAAE;QACN,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QAChC,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QAClC,iBAAiB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QACvC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;KACjC,GAAG,SAAS,CAAC;IACd,cAAc,CAAC,EAAE;QAAE,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,GAAG,SAAS,CAAC;IACrE,eAAe,CAAC,EAAE;QAChB,gBAAgB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QACtC,mBAAmB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QACzC,kBAAkB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QACxC,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;KACtC,GAAG,SAAS,CAAC;IACd,eAAe,CAAC,EAAE;QAChB,mBAAmB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QACzC,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QACrC,uBAAuB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;KAC9C,GAAG,SAAS,CAAC;IACd,gBAAgB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACvC;AAED,gCAAgC;AAChC,MAAM,WAAW,mBAAmB;IAClC,qCAAqC;IACrC,EAAE,EAAE,OAAO,CAAC;IACZ,QAAQ,EAAE,KAAK,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,OAAO,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;QAClB,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QAC5B,SAAS,EAAE,KAAK,CAAC;YAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;YAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;YAAC,MAAM,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAA;SAAE,CAAC,CAAC;QACpG,OAAO,EAAE,MAAM,EAAE,CAAC;KACnB,CAAC,CAAC;CACJ"}
package/dist/types.js ADDED
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Type definitions of the procedures of this package
3
+ *
4
+ * mark procedure new adds the types of each new procedure here. The zod schemas are in
5
+ * `module.ts`: an exported schema needs a written type (isolatedDeclarations).
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
package/package.json CHANGED
@@ -1,6 +1,81 @@
1
1
  {
2
+ "$schema": "https://json.schemastore.org/package",
2
3
  "name": "@procedures/systems",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
4
+ "version": "0.2.3",
5
+ "description": "The timer law of systems for the client: it binds the times of the middleware, the transports and the server to the symbols of the law, and examines the rules of the client.",
6
+ "keywords": [
7
+ "procedures",
8
+ "timeouts",
9
+ "retry",
10
+ "heartbeat",
11
+ "timer-law",
12
+ "lint",
13
+ "resilience"
14
+ ],
15
+ "homepage": "https://mark1russell7.github.io/client/",
16
+ "bugs": {
17
+ "url": "https://github.com/mark1russell7/client/issues"
18
+ },
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "git+https://github.com/mark1russell7/client.git",
22
+ "directory": "packages/systems"
23
+ },
24
+ "license": "MIT",
25
+ "author": "Mark Russell (https://github.com/mark1russell7)",
26
+ "type": "module",
27
+ "main": "./dist/index.js",
28
+ "types": "./dist/index.d.ts",
29
+ "exports": {
30
+ ".": {
31
+ "types": "./dist/index.d.ts",
32
+ "import": "./dist/index.js"
33
+ },
34
+ "./module": {
35
+ "types": "./dist/module.d.ts",
36
+ "import": "./dist/module.js"
37
+ },
38
+ "./register": {
39
+ "types": "./dist/register.d.ts",
40
+ "import": "./dist/register.js"
41
+ }
42
+ },
43
+ "files": [
44
+ "dist",
45
+ "src",
46
+ "!src/**/*.test.ts",
47
+ "!src/**/*.test.tsx",
48
+ "!src/**/__tests__",
49
+ "CHANGELOG.md"
50
+ ],
51
+ "sideEffects": [
52
+ "./dist/register.js"
53
+ ],
54
+ "devDependencies": {
55
+ "@mark1russell7/cue": "^1.0.0",
56
+ "typescript": "^7.0.2",
57
+ "vitest": "^5.0.3"
58
+ },
59
+ "engines": {
60
+ "node": ">=22"
61
+ },
62
+ "client": {
63
+ "procedures": "./dist/register.js"
64
+ },
65
+ "dependencies": {
66
+ "@mark1russell7/service": "^0.4.0",
67
+ "@procedures/client": "0.2.3",
68
+ "zod": "^4.6.5"
69
+ },
70
+ "publishConfig": {
71
+ "access": "public",
72
+ "provenance": true
73
+ },
74
+ "scripts": {
75
+ "build": "tsc -b",
76
+ "typecheck": "tsc --noEmit",
77
+ "clean": "rm -rf dist .tsbuildinfo",
78
+ "test": "vitest run",
79
+ "test:watch": "vitest"
80
+ }
6
81
  }
package/src/index.ts ADDED
@@ -0,0 +1,7 @@
1
+ // The root registers nothing: import "<package>/register", or give the module to createRegistry()
2
+ export * from "./module.js";
3
+ export * from "./types.js";
4
+ export { CLIENT_RULES } from "./rules.js";
5
+ export { bindingOf, lintTimers } from "./lint.js";
6
+ export type { TimerFinding, TimerSettings } from "./lint.js";
7
+ export { settingsOf } from "./procedures/systems/timers.js";