stitchkit 0.76.2 → 0.77.0

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.
@@ -30,10 +30,13 @@ import {
30
30
  } from "./index-a916km3r.js";
31
31
  import {
32
32
  ApplicationAdmissionError,
33
+ ApplicationRestartInputSchema,
34
+ ApplicationRestartOutcomeSchema,
35
+ ApplicationRestartResultSchema,
33
36
  ApplicationShutdownBudgetSchema,
34
37
  ApplicationShutdownOptionsSchema,
35
38
  createApplication
36
- } from "./index-hvftzz91.js";
39
+ } from "./index-vc1b0b1b.js";
37
40
  import {
38
41
  defineManagedResource,
39
42
  managedResourceDependencyId
@@ -430,23 +433,84 @@ function createBoundedAdmission(config) {
430
433
  getSnapshot
431
434
  };
432
435
  }
436
+ // src/internal/decision.ts
437
+ import { z as z2 } from "zod";
438
+ var PolicyDecisionSchema = z2.discriminatedUnion("outcome", [
439
+ z2.object({ outcome: z2.literal("allow") }).strict(),
440
+ z2.object({ outcome: z2.literal("deny"), reason: z2.string().min(1) }).strict(),
441
+ z2.object({ outcome: z2.literal("defer") }).strict()
442
+ ]);
443
+
444
+ // src/application/decisions.ts
445
+ class DecisionUndecidedError extends Error {
446
+ trace;
447
+ constructor(trace) {
448
+ const ran = trace.length === 0 ? "no policy ran" : trace.map((e) => e.id).join(" → ");
449
+ super(`Decision pipeline reached its end with no terminal verdict (${ran}). A pipeline needs a policy that answers allow or deny.`);
450
+ this.name = "DecisionUndecidedError";
451
+ this.trace = trace;
452
+ }
453
+ }
454
+
455
+ class DecisionPolicyError extends Error {
456
+ policyId;
457
+ constructor(policyId, detail) {
458
+ super(`Policy "${policyId}" did not return a decision (${detail}). A policy returns { outcome: "allow" | "deny" | "defer" }, and a deny carries a reason.`);
459
+ this.name = "DecisionPolicyError";
460
+ this.policyId = policyId;
461
+ }
462
+ }
463
+ function createDecisionPipeline(policies) {
464
+ const seen = new Set;
465
+ for (const policy of policies) {
466
+ if (policy.id.trim() === "") {
467
+ throw new Error("[stitchkit] decision pipeline: a policy needs a non-empty id.");
468
+ }
469
+ if (seen.has(policy.id)) {
470
+ throw new Error(`[stitchkit] decision pipeline: two policies share the id "${policy.id}". The trace names policies by id, and a duplicate makes it ambiguous exactly when it is read to explain a refusal.`);
471
+ }
472
+ seen.add(policy.id);
473
+ }
474
+ return {
475
+ policyIds: policies.map((policy) => policy.id),
476
+ async decide(input) {
477
+ const trace = [];
478
+ for (const policy of policies) {
479
+ const answer = await policy.decide(input);
480
+ const parsed = PolicyDecisionSchema.safeParse(answer);
481
+ if (!parsed.success) {
482
+ throw new DecisionPolicyError(policy.id, parsed.error.issues[0]?.message ?? "invalid");
483
+ }
484
+ const decision = parsed.data;
485
+ trace.push(decision.outcome === "deny" ? { id: policy.id, outcome: "deny", reason: decision.reason } : { id: policy.id, outcome: decision.outcome });
486
+ if (decision.outcome === "deny") {
487
+ return { outcome: "deny", reason: decision.reason, trace };
488
+ }
489
+ if (decision.outcome === "allow") {
490
+ return { outcome: "allow", trace };
491
+ }
492
+ }
493
+ throw new DecisionUndecidedError(trace);
494
+ }
495
+ };
496
+ }
433
497
  // src/application/diagnostic-journal.ts
434
498
  import { randomUUID } from "node:crypto";
435
499
 
436
500
  // src/application/diagnostic-journal-contract.ts
437
- import { z as z2 } from "zod";
438
- var PositiveSafeIntegerSchema2 = z2.number().int().positive().safe();
439
- var FileModeSchema = z2.number().int().min(0).max(511);
440
- var DiagnosticJournalLimitsSchema = z2.object({
501
+ import { z as z3 } from "zod";
502
+ var PositiveSafeIntegerSchema2 = z3.number().int().positive().safe();
503
+ var FileModeSchema = z3.number().int().min(0).max(511);
504
+ var DiagnosticJournalLimitsSchema = z3.object({
441
505
  maxEventBytes: PositiveSafeIntegerSchema2,
442
506
  maxPendingItems: PositiveSafeIntegerSchema2,
443
507
  maxPendingBytes: PositiveSafeIntegerSchema2,
444
508
  maxFileBytes: PositiveSafeIntegerSchema2,
445
509
  maxFiles: PositiveSafeIntegerSchema2
446
510
  }).strict().readonly();
447
- var DiagnosticJournalLockPolicySchema = z2.enum(["refuse", "reclaim-stale"]);
448
- var DiagnosticJournalStateSchema = z2.enum(["open", "draining", "closed", "failed"]);
449
- var DiagnosticJournalRefusalReasonSchema = z2.enum([
511
+ var DiagnosticJournalLockPolicySchema = z3.enum(["refuse", "reclaim-stale"]);
512
+ var DiagnosticJournalStateSchema = z3.enum(["open", "draining", "closed", "failed"]);
513
+ var DiagnosticJournalRefusalReasonSchema = z3.enum([
450
514
  "closed",
451
515
  "failed",
452
516
  "invalid",
@@ -454,72 +518,72 @@ var DiagnosticJournalRefusalReasonSchema = z2.enum([
454
518
  "item-capacity",
455
519
  "byte-capacity"
456
520
  ]);
457
- var DiagnosticJournalRefusalCountersSchema = z2.object({
458
- closed: z2.number().int().nonnegative(),
459
- failed: z2.number().int().nonnegative(),
460
- invalid: z2.number().int().nonnegative(),
461
- oversized: z2.number().int().nonnegative(),
462
- "item-capacity": z2.number().int().nonnegative(),
463
- "byte-capacity": z2.number().int().nonnegative()
521
+ var DiagnosticJournalRefusalCountersSchema = z3.object({
522
+ closed: z3.number().int().nonnegative(),
523
+ failed: z3.number().int().nonnegative(),
524
+ invalid: z3.number().int().nonnegative(),
525
+ oversized: z3.number().int().nonnegative(),
526
+ "item-capacity": z3.number().int().nonnegative(),
527
+ "byte-capacity": z3.number().int().nonnegative()
464
528
  }).strict().readonly();
465
- var DiagnosticJournalFailurePhaseSchema = z2.enum(["write", "rotation", "close"]);
466
- var DiagnosticJournalStatusSchema = z2.object({
529
+ var DiagnosticJournalFailurePhaseSchema = z3.enum(["write", "rotation", "close"]);
530
+ var DiagnosticJournalStatusSchema = z3.object({
467
531
  state: DiagnosticJournalStateSchema,
468
- epoch: z2.uuid(),
532
+ epoch: z3.uuid(),
469
533
  limits: DiagnosticJournalLimitsSchema,
470
- lock: z2.object({
534
+ lock: z3.object({
471
535
  policy: DiagnosticJournalLockPolicySchema,
472
- reclaimedStale: z2.boolean()
536
+ reclaimedStale: z3.boolean()
473
537
  }).strict().readonly(),
474
- received: z2.number().int().nonnegative(),
475
- accepted: z2.number().int().nonnegative(),
476
- refused: z2.number().int().nonnegative(),
538
+ received: z3.number().int().nonnegative(),
539
+ accepted: z3.number().int().nonnegative(),
540
+ refused: z3.number().int().nonnegative(),
477
541
  refusals: DiagnosticJournalRefusalCountersSchema,
478
- written: z2.number().int().nonnegative(),
479
- failedRecords: z2.number().int().nonnegative(),
480
- pendingItems: z2.number().int().nonnegative(),
481
- pendingBytes: z2.number().int().nonnegative(),
482
- inFlight: z2.boolean(),
483
- rotations: z2.number().int().nonnegative(),
484
- rotationFailures: z2.number().int().nonnegative(),
485
- partialTails: z2.number().int().nonnegative(),
486
- currentFileBytes: z2.number().int().nonnegative(),
487
- retainedFiles: z2.number().int().nonnegative(),
488
- lastAcceptedSequence: z2.number().int().positive().optional(),
489
- lastWrittenSequence: z2.number().int().positive().optional(),
490
- lastSettledSequence: z2.number().int().positive().optional(),
491
- lastFailure: z2.object({
542
+ written: z3.number().int().nonnegative(),
543
+ failedRecords: z3.number().int().nonnegative(),
544
+ pendingItems: z3.number().int().nonnegative(),
545
+ pendingBytes: z3.number().int().nonnegative(),
546
+ inFlight: z3.boolean(),
547
+ rotations: z3.number().int().nonnegative(),
548
+ rotationFailures: z3.number().int().nonnegative(),
549
+ partialTails: z3.number().int().nonnegative(),
550
+ currentFileBytes: z3.number().int().nonnegative(),
551
+ retainedFiles: z3.number().int().nonnegative(),
552
+ lastAcceptedSequence: z3.number().int().positive().optional(),
553
+ lastWrittenSequence: z3.number().int().positive().optional(),
554
+ lastSettledSequence: z3.number().int().positive().optional(),
555
+ lastFailure: z3.object({
492
556
  phase: DiagnosticJournalFailurePhaseSchema,
493
- sequence: z2.number().int().positive().optional()
557
+ sequence: z3.number().int().positive().optional()
494
558
  }).strict().readonly().optional()
495
559
  }).strict().readonly();
496
- var DiagnosticJournalSubmitResultSchema = z2.discriminatedUnion("outcome", [
497
- z2.object({
498
- outcome: z2.literal("accepted"),
499
- epoch: z2.uuid(),
500
- sequence: z2.number().int().positive()
560
+ var DiagnosticJournalSubmitResultSchema = z3.discriminatedUnion("outcome", [
561
+ z3.object({
562
+ outcome: z3.literal("accepted"),
563
+ epoch: z3.uuid(),
564
+ sequence: z3.number().int().positive()
501
565
  }).strict().readonly(),
502
- z2.object({
503
- outcome: z2.literal("refused"),
566
+ z3.object({
567
+ outcome: z3.literal("refused"),
504
568
  reason: DiagnosticJournalRefusalReasonSchema
505
569
  }).strict().readonly()
506
570
  ]);
507
- var DiagnosticJournalWaitResultSchema = z2.object({
508
- outcome: z2.enum(["settled", "timed-out", "cancelled"]),
571
+ var DiagnosticJournalWaitResultSchema = z3.object({
572
+ outcome: z3.enum(["settled", "timed-out", "cancelled"]),
509
573
  state: DiagnosticJournalStateSchema,
510
- throughSequence: z2.number().int().nonnegative(),
511
- settledSequence: z2.number().int().nonnegative()
574
+ throughSequence: z3.number().int().nonnegative(),
575
+ settledSequence: z3.number().int().nonnegative()
512
576
  }).strict().readonly();
513
- var DiagnosticJournalCloseResultSchema = z2.object({
514
- outcome: z2.enum(["closed", "timed-out", "cancelled"]),
577
+ var DiagnosticJournalCloseResultSchema = z3.object({
578
+ outcome: z3.enum(["closed", "timed-out", "cancelled"]),
515
579
  state: DiagnosticJournalStateSchema,
516
- pendingItems: z2.number().int().nonnegative()
580
+ pendingItems: z3.number().int().nonnegative()
517
581
  }).strict().readonly();
518
- var DiagnosticJournalFrameSchema = z2.object({
519
- schemaVersion: z2.literal(1),
520
- epoch: z2.uuid(),
521
- sequence: z2.number().int().positive(),
522
- event: z2.json()
582
+ var DiagnosticJournalFrameSchema = z3.object({
583
+ schemaVersion: z3.literal(1),
584
+ epoch: z3.uuid(),
585
+ sequence: z3.number().int().positive(),
586
+ event: z3.json()
523
587
  }).strict().readonly();
524
588
  function parseDiagnosticJournalMode(mode) {
525
589
  return FileModeSchema.parse(mode ?? 384);
@@ -532,7 +596,7 @@ function readDiagnosticJournalLockDiagnosis(error) {
532
596
  }
533
597
 
534
598
  // src/application/diagnostic-journal-manager.ts
535
- import { z as z3 } from "zod";
599
+ import { z as z4 } from "zod";
536
600
 
537
601
  // src/application/diagnostic-journal-storage.ts
538
602
  import { constants as constants2 } from "node:fs";
@@ -1058,7 +1122,7 @@ function createDiagnosticJournalManager(config, storage) {
1058
1122
  const parsed = config.eventSchema.safeParse(event);
1059
1123
  if (!parsed.success)
1060
1124
  return refuse("invalid");
1061
- const json = z3.json().safeParse(parsed.data);
1125
+ const json = z4.json().safeParse(parsed.data);
1062
1126
  if (!json.success)
1063
1127
  return refuse("invalid");
1064
1128
  const payload = encoder.encode(JSON.stringify(json.data));
@@ -1141,17 +1205,17 @@ async function createDiagnosticJournal(config) {
1141
1205
  }, storage);
1142
1206
  }
1143
1207
  // src/application/events.ts
1144
- import { z as z4 } from "zod";
1145
- var ApplicationLifecycleEventSchema = z4.object({
1146
- type: z4.literal("application-state"),
1208
+ import { z as z5 } from "zod";
1209
+ var ApplicationLifecycleEventSchema = z5.object({
1210
+ type: z5.literal("application-state"),
1147
1211
  applicationId: ApplicationIdSchema,
1148
- epoch: z4.string().uuid(),
1149
- revision: z4.number().int().nonnegative(),
1212
+ epoch: z5.string().uuid(),
1213
+ revision: z5.number().int().nonnegative(),
1150
1214
  lifecycle: ApplicationLifecycleSchema,
1151
1215
  health: ApplicationHealthSchema,
1152
- ready: z4.boolean(),
1153
- capturedAt: z4.string().datetime({ offset: true }),
1154
- resources: z4.array(ManagedResourceSnapshotSchema).readonly()
1216
+ ready: z5.boolean(),
1217
+ capturedAt: z5.string().datetime({ offset: true }),
1218
+ resources: z5.array(ManagedResourceSnapshotSchema).readonly()
1155
1219
  }).strict().readonly();
1156
1220
  function applicationLifecycleEvent(snapshot) {
1157
1221
  return ApplicationLifecycleEventSchema.parse({
@@ -1182,13 +1246,13 @@ function createApplicationEventSink(config) {
1182
1246
  };
1183
1247
  }
1184
1248
  // src/application/health.ts
1185
- import { z as z5 } from "zod";
1186
- var ApplicationHealthHandlerOptionsSchema = z5.object({
1187
- kind: z5.enum(["liveness", "readiness"]),
1188
- retryAfterSeconds: z5.number().int().nonnegative().default(5)
1249
+ import { z as z6 } from "zod";
1250
+ var ApplicationHealthHandlerOptionsSchema = z6.object({
1251
+ kind: z6.enum(["liveness", "readiness"]),
1252
+ retryAfterSeconds: z6.number().int().nonnegative().default(5)
1189
1253
  });
1190
- var ApplicationOperationalHandlersOptionsSchema = z5.object({
1191
- retryAfterSeconds: z5.number().int().nonnegative().default(5)
1254
+ var ApplicationOperationalHandlersOptionsSchema = z6.object({
1255
+ retryAfterSeconds: z6.number().int().nonnegative().default(5)
1192
1256
  });
1193
1257
  function createApplicationHealthHandler(application, options) {
1194
1258
  const parsed = ApplicationHealthHandlerOptionsSchema.parse(options);
@@ -1430,12 +1494,12 @@ function managedServerResource(config) {
1430
1494
  });
1431
1495
  }
1432
1496
  // src/browser/resumable.ts
1433
- import { z as z6 } from "zod";
1434
- var PositiveSafeIntegerSchema3 = z6.number().int().positive().safe();
1435
- var BackoffPolicySchema = z6.object({
1497
+ import { z as z7 } from "zod";
1498
+ var PositiveSafeIntegerSchema3 = z7.number().int().positive().safe();
1499
+ var BackoffPolicySchema = z7.object({
1436
1500
  minDelayMs: PositiveSafeIntegerSchema3,
1437
1501
  maxDelayMs: PositiveSafeIntegerSchema3,
1438
- jitter: z6.number().min(0).max(1)
1502
+ jitter: z7.number().min(0).max(1)
1439
1503
  }).strict().readonly().refine((policy) => policy.maxDelayMs >= policy.minDelayMs, {
1440
1504
  message: "maxDelayMs must be at least minDelayMs"
1441
1505
  });
@@ -1456,12 +1520,12 @@ function createBackoff(policy, random = Math.random) {
1456
1520
  }
1457
1521
 
1458
1522
  // src/live/watch-contract.ts
1459
- import { z as z8 } from "zod";
1523
+ import { z as z9 } from "zod";
1460
1524
 
1461
1525
  // src/browser/live-state.ts
1462
- import { z as z7 } from "zod";
1463
- var PositiveSafeIntegerSchema4 = z7.number().int().positive().safe();
1464
- var LiveStatePhaseSchema = z7.enum([
1526
+ import { z as z8 } from "zod";
1527
+ var PositiveSafeIntegerSchema4 = z8.number().int().positive().safe();
1528
+ var LiveStatePhaseSchema = z8.enum([
1465
1529
  "idle",
1466
1530
  "opening",
1467
1531
  "live",
@@ -1469,7 +1533,7 @@ var LiveStatePhaseSchema = z7.enum([
1469
1533
  "unavailable",
1470
1534
  "closed"
1471
1535
  ]);
1472
- var LiveStateStopReasonSchema = z7.enum([
1536
+ var LiveStateStopReasonSchema = z8.enum([
1473
1537
  "gap",
1474
1538
  "buffer-overflow",
1475
1539
  "source-unavailable",
@@ -1477,42 +1541,42 @@ var LiveStateStopReasonSchema = z7.enum([
1477
1541
  "controller-error",
1478
1542
  "controller-capacity"
1479
1543
  ]);
1480
- var LiveStateControllerStatusSchema = z7.object({
1544
+ var LiveStateControllerStatusSchema = z8.object({
1481
1545
  phase: LiveStatePhaseSchema,
1482
- generation: z7.number().int().nonnegative(),
1483
- hasValue: z7.boolean(),
1484
- bufferedEvents: z7.number().int().nonnegative(),
1485
- bufferedBytes: z7.number().int().nonnegative(),
1486
- receivedEvents: z7.number().int().nonnegative(),
1487
- appliedEvents: z7.number().int().nonnegative(),
1488
- duplicateEvents: z7.number().int().nonnegative(),
1489
- gapEvents: z7.number().int().nonnegative(),
1490
- refusedEvents: z7.number().int().nonnegative(),
1546
+ generation: z8.number().int().nonnegative(),
1547
+ hasValue: z8.boolean(),
1548
+ bufferedEvents: z8.number().int().nonnegative(),
1549
+ bufferedBytes: z8.number().int().nonnegative(),
1550
+ receivedEvents: z8.number().int().nonnegative(),
1551
+ appliedEvents: z8.number().int().nonnegative(),
1552
+ duplicateEvents: z8.number().int().nonnegative(),
1553
+ gapEvents: z8.number().int().nonnegative(),
1554
+ refusedEvents: z8.number().int().nonnegative(),
1491
1555
  reason: LiveStateStopReasonSchema.optional()
1492
1556
  }).strict().readonly();
1493
1557
 
1494
1558
  // src/live/watch-contract.ts
1495
- var WatchKeySchema = z8.object({
1496
- service: z8.string().min(1),
1497
- action: z8.string().min(1),
1498
- digest: z8.string().min(1)
1559
+ var WatchKeySchema = z9.object({
1560
+ service: z9.string().min(1),
1561
+ action: z9.string().min(1),
1562
+ digest: z9.string().min(1)
1499
1563
  }).strict().readonly();
1500
- var WatchOpenSchema = z8.object({ key: WatchKeySchema, args: z8.unknown() }).readonly();
1501
- var WatchAcceptedSchema = z8.object({
1502
- accepted: z8.boolean(),
1503
- reason: z8.string().optional()
1564
+ var WatchOpenSchema = z9.object({ key: WatchKeySchema, args: z9.unknown() }).readonly();
1565
+ var WatchAcceptedSchema = z9.object({
1566
+ accepted: z9.boolean(),
1567
+ reason: z9.string().optional()
1504
1568
  }).strict().readonly();
1505
- var WatchValueSchema = z8.object({
1569
+ var WatchValueSchema = z9.object({
1506
1570
  key: WatchKeySchema,
1507
- revision: z8.number().int().nonnegative(),
1508
- value: z8.unknown()
1571
+ revision: z9.number().int().nonnegative(),
1572
+ value: z9.unknown()
1509
1573
  }).readonly();
1510
- var WatchStateSchema = z8.object({
1574
+ var WatchStateSchema = z9.object({
1511
1575
  key: WatchKeySchema,
1512
1576
  phase: LiveStatePhaseSchema,
1513
1577
  reason: LiveStateStopReasonSchema.optional(),
1514
- code: z8.string().optional(),
1515
- message: z8.string().optional()
1578
+ code: z9.string().optional(),
1579
+ message: z9.string().optional()
1516
1580
  }).readonly();
1517
1581
  var WATCH_OPEN = "stitchkit.watch.open";
1518
1582
  var WATCH_CLOSE = "stitchkit.watch.close";
@@ -1520,12 +1584,12 @@ var WATCH_VALUE = "stitchkit.watch.value";
1520
1584
  var WATCH_STATE = "stitchkit.watch.state";
1521
1585
  var watchContract = {
1522
1586
  serverToClient: {
1523
- [WATCH_VALUE]: { args: z8.tuple([WatchValueSchema]) },
1524
- [WATCH_STATE]: { args: z8.tuple([WatchStateSchema]) }
1587
+ [WATCH_VALUE]: { args: z9.tuple([WatchValueSchema]) },
1588
+ [WATCH_STATE]: { args: z9.tuple([WatchStateSchema]) }
1525
1589
  },
1526
1590
  clientToServer: {
1527
- [WATCH_OPEN]: { args: z8.tuple([WatchOpenSchema]), ack: WatchAcceptedSchema },
1528
- [WATCH_CLOSE]: { args: z8.tuple([z8.object({ key: WatchKeySchema }).readonly()]) }
1591
+ [WATCH_OPEN]: { args: z9.tuple([WatchOpenSchema]), ack: WatchAcceptedSchema },
1592
+ [WATCH_CLOSE]: { args: z9.tuple([z9.object({ key: WatchKeySchema }).readonly()]) }
1529
1593
  }
1530
1594
  };
1531
1595
  function watchKeyString(key) {
@@ -1756,6 +1820,7 @@ export {
1756
1820
  createWatchHub,
1757
1821
  createManagedSchedule,
1758
1822
  createDiagnosticJournal,
1823
+ createDecisionPipeline,
1759
1824
  createCreditWindow,
1760
1825
  createBoundedChannel,
1761
1826
  createBoundedAdmission,
@@ -1766,6 +1831,7 @@ export {
1766
1831
  createApplication,
1767
1832
  createActivityProjection,
1768
1833
  applicationLifecycleEvent,
1834
+ PolicyDecisionSchema,
1769
1835
  ManagedScheduleStatusSchema,
1770
1836
  ManagedScheduleOverlapSchema,
1771
1837
  ManagedScheduleErrorPolicySchema,
@@ -1782,6 +1848,8 @@ export {
1782
1848
  DiagnosticJournalFrameSchema,
1783
1849
  DiagnosticJournalFailurePhaseSchema,
1784
1850
  DiagnosticJournalCloseResultSchema,
1851
+ DecisionUndecidedError,
1852
+ DecisionPolicyError,
1785
1853
  CreditWindowSnapshotSchema,
1786
1854
  BoundedRateBudgetSchema,
1787
1855
  BoundedOperationWaitError,
@@ -1801,6 +1869,9 @@ export {
1801
1869
  ApplicationShutdownResultSchema,
1802
1870
  ApplicationShutdownOptionsSchema,
1803
1871
  ApplicationShutdownBudgetSchema,
1872
+ ApplicationRestartResultSchema,
1873
+ ApplicationRestartOutcomeSchema,
1874
+ ApplicationRestartInputSchema,
1804
1875
  ApplicationResourceShutdownSchema,
1805
1876
  ApplicationOperationalHandlersOptionsSchema,
1806
1877
  ApplicationLifecycleSchema,