camstack 1.2.202 → 1.2.203

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.
@@ -24024,9 +24024,9 @@ var require_zod = __commonJS({
24024
24024
  }
24025
24025
  });
24026
24026
 
24027
- // ../system/dist/dist-Dwi4JA96.js
24028
- var require_dist_Dwi4JA96 = __commonJS({
24029
- "../system/dist/dist-Dwi4JA96.js"(exports) {
24027
+ // ../system/dist/dist-QyW9hVO2.js
24028
+ var require_dist_QyW9hVO2 = __commonJS({
24029
+ "../system/dist/dist-QyW9hVO2.js"(exports) {
24030
24030
  "use strict";
24031
24031
  var zod = require_zod();
24032
24032
  __require("crypto");
@@ -24110,6 +24110,8 @@ var require_dist_Dwi4JA96 = __commonJS({
24110
24110
  EventCategory2["PipelineCameraUnassigned"] = "pipeline.camera-unassigned";
24111
24111
  EventCategory2["PipelineNodeInferenceUnavailable"] = "pipeline.node-inference-unavailable";
24112
24112
  EventCategory2["PipelineDetectionBlind"] = "pipeline.detection-blind";
24113
+ EventCategory2["PipelineMotionNoisy"] = "pipeline.motion-noisy";
24114
+ EventCategory2["PipelineMotionCalm"] = "pipeline.motion-calm";
24113
24115
  EventCategory2["PipelineCameraUpdated"] = "pipeline.camera-updated";
24114
24116
  EventCategory2["PipelineIngestOwnerChanged"] = "pipeline.ingest-owner-changed";
24115
24117
  EventCategory2["PipelineRunnerLoadSnapshot"] = "pipeline.runner-load-snapshot";
@@ -26475,6 +26477,12 @@ var require_dist_Dwi4JA96 = __commonJS({
26475
26477
  this.name = "BatchTooLargeError";
26476
26478
  }
26477
26479
  };
26480
+ var TransactRefusedError = class extends RecordsError {
26481
+ constructor(detail) {
26482
+ super("transact-refused", detail);
26483
+ this.name = "TransactRefusedError";
26484
+ }
26485
+ };
26478
26486
  function defOf(schema) {
26479
26487
  const zodBag = Reflect.get(schema, "_zod");
26480
26488
  if (typeof zodBag !== "object" || zodBag === null) return {};
@@ -26655,7 +26663,7 @@ var require_dist_Dwi4JA96 = __commonJS({
26655
26663
  /** JSON Schema of the entry body; `secret: true` marks a password field. */
26656
26664
  fields: zod.z.record(zod.z.string(), zod.z.unknown())
26657
26665
  }).strict();
26658
- var RecordKindDeclarationSchema = zod.z.object({
26666
+ var RecordKindDeclarationShape = zod.z.object({
26659
26667
  database: zod.z.enum(RECORD_DATABASES).default("settings"),
26660
26668
  class: zod.z.enum(RECORD_CLASSES),
26661
26669
  writeTrigger: zod.z.string().min(1),
@@ -26673,18 +26681,12 @@ var require_dist_Dwi4JA96 = __commonJS({
26673
26681
  secretPaths: zod.z.array(zod.z.string().min(1)).default([]),
26674
26682
  /** The id key of each array that carries a secret (`{ headers: 'name' }`). */
26675
26683
  secretArrayKeys: zod.z.record(zod.z.string(), zod.z.string()).default({}),
26676
- /**
26677
- * RETIRED (D900): the legacy table a kind adopted from during the records
26678
- * migration. Nothing declares it any more and nothing reads it; the schema
26679
- * still ACCEPTS it because the catalog rows the migration wrote carry it
26680
- * (an orphaned kind is never redeclared) and an addon built before the
26681
- * removal still sends it. Never set it.
26682
- */
26683
- adoptsFrom: zod.z.string().min(1).optional(),
26684
26684
  /** Kinds that must agree through `transact` sit in one file under one family name. */
26685
26685
  transactFamily: zod.z.string().min(1).optional(),
26686
26686
  entry: EntryDescriptorSchema.optional()
26687
- }).strict();
26687
+ });
26688
+ var RecordKindDeclarationSchema = RecordKindDeclarationShape.strict();
26689
+ var StoredRecordKindDeclarationSchema = RecordKindDeclarationShape;
26688
26690
  var RecordKindNameSchema = zod.z.string().regex(/^[a-z][a-z0-9-]{0,47}$/);
26689
26691
  function assertValidDeclaration(name, decl) {
26690
26692
  const refuse = (why) => {
@@ -26762,6 +26764,16 @@ var require_dist_Dwi4JA96 = __commonJS({
26762
26764
  }
26763
26765
  return out;
26764
26766
  }
26767
+ function assertTransactScope(members) {
26768
+ const byKind = /* @__PURE__ */ new Map();
26769
+ for (const m of members) byKind.set(m.kind, m);
26770
+ const kinds = [...byKind.values()];
26771
+ if (new Set(kinds.map((m) => m.declaration.database)).size > 1) throw new TransactRefusedError(`cross-file: the ops span more than one database file (${kinds.map((m) => `${m.kind}@${m.declaration.database}`).join(", ")}); a transaction lives in ONE file`);
26772
+ if (kinds.length <= 1) return;
26773
+ const missing = kinds.filter((m) => m.declaration.transactFamily === void 0);
26774
+ if (missing.length > 0) throw new TransactRefusedError(`no-family: ${missing.map((m) => m.kind).join(", ")} declare no transactFamily; kinds that must agree through transact share one`);
26775
+ if (new Set(kinds.map((m) => m.declaration.transactFamily)).size > 1) throw new TransactRefusedError(`cross-family: the ops span more than one transactFamily (${kinds.map((m) => `${m.kind}=${String(m.declaration.transactFamily)}`).join(", ")})`);
26776
+ }
26765
26777
  var CamProfileSchema = zod.z.enum([
26766
26778
  "high",
26767
26779
  "mid",
@@ -31484,17 +31496,6 @@ var require_dist_Dwi4JA96 = __commonJS({
31484
31496
  createdAt: zod.z.number(),
31485
31497
  updatedAt: zod.z.number()
31486
31498
  });
31487
- var ApiKeyRecordSchema = zod.z.object({
31488
- id: zod.z.string(),
31489
- label: zod.z.string(),
31490
- isAdmin: zod.z.boolean().default(false),
31491
- allowedProviders: AllowedProviderSchema,
31492
- allowedDevices: AllowedDevicesSchema,
31493
- tokenHash: zod.z.string(),
31494
- tokenPrefix: zod.z.string(),
31495
- createdAt: zod.z.number(),
31496
- lastUsedAt: zod.z.number().optional()
31497
- });
31498
31499
  var ScopedTokenSchema = zod.z.object({
31499
31500
  id: zod.z.string(),
31500
31501
  userId: zod.z.string(),
@@ -36858,15 +36859,31 @@ var require_dist_Dwi4JA96 = __commonJS({
36858
36859
  var DeclareKindResultSchema = zod.z.object({
36859
36860
  kindId: zod.z.number().int(),
36860
36861
  state: RecordKindStateSchema,
36861
- createdIndexes: zod.z.array(zod.z.string()),
36862
- /**
36863
- * RETIRED (D900): always `null`. It carried the records-migration boot guard;
36864
- * it stays on the wire, null, because an addon built before the removal reads
36865
- * an ABSENT field as "adoption pending" and refuses to start.
36866
- */
36867
- adoptionPending: zod.z.null()
36862
+ createdIndexes: zod.z.array(zod.z.string())
36868
36863
  });
36869
36864
  var SecretRefsList = zod.z.array(zod.z.string());
36865
+ var RecordTransactOpSchema = zod.z.discriminatedUnion("op", [
36866
+ zod.z.object({
36867
+ op: zod.z.literal("put"),
36868
+ kind: RecordKindNameSchema,
36869
+ record: RecordInputSchema,
36870
+ ifRev: zod.z.number().int().min(0).optional()
36871
+ }),
36872
+ zod.z.object({
36873
+ op: zod.z.literal("patch"),
36874
+ kind: RecordKindNameSchema,
36875
+ id: RecordIdSchema,
36876
+ data: RecordBodySchema,
36877
+ at: zod.z.number().int().nullable().optional(),
36878
+ expiresAt: zod.z.number().int().nullable().optional(),
36879
+ ifRev: zod.z.number().int().min(1).optional()
36880
+ }),
36881
+ zod.z.object({
36882
+ op: zod.z.literal("delete"),
36883
+ kind: RecordKindNameSchema,
36884
+ id: RecordIdSchema
36885
+ })
36886
+ ]);
36870
36887
  var RecordSecretRefsSchema = zod.z.record(zod.z.string(), zod.z.record(zod.z.string(), zod.z.string()));
36871
36888
  var recordsCapability = {
36872
36889
  name: "records",
@@ -36998,6 +37015,22 @@ var require_dist_Dwi4JA96 = __commonJS({
36998
37015
  kind: "mutation",
36999
37016
  auth: "admin"
37000
37017
  }),
37018
+ /**
37019
+ * Several single-row writes (put / patch / delete) in ONE SQLite transaction:
37020
+ * all land or none does. Every op's kind must sit in one file and share one
37021
+ * `transactFamily` (`records/transact-refused` otherwise). Results are in op order.
37022
+ */
37023
+ transact: method(zod.z.object({ ops: zod.z.array(RecordTransactOpSchema).min(1).max(RECORD_BATCH_MAX) }), zod.z.object({
37024
+ results: zod.z.array(zod.z.object({
37025
+ rev: zod.z.number().int().nullable(),
37026
+ deleted: zod.z.boolean()
37027
+ })),
37028
+ releasedRefs: SecretRefsList,
37029
+ secretRefs: SecretRefsList
37030
+ }), {
37031
+ kind: "mutation",
37032
+ auth: "admin"
37033
+ }),
37001
37034
  /** The D865 hook body: every kind of this addon declared `deviceRemoval: 'delete'`. */
37002
37035
  deleteDevice: method(zod.z.object({
37003
37036
  deviceId: zod.z.number().int(),
@@ -63094,9 +63127,13 @@ var require_dist_Dwi4JA96 = __commonJS({
63094
63127
  "node-updating",
63095
63128
  "node-inference-unavailable",
63096
63129
  "detection-blind",
63130
+ "motion-noisy",
63131
+ "motion-calm",
63097
63132
  "recording-stalled",
63098
63133
  "recording-healthy",
63099
63134
  "recording-degraded",
63135
+ "device-attention-required",
63136
+ "device-attention-resolved",
63100
63137
  "storage-location-low",
63101
63138
  "storage-location-critical",
63102
63139
  "storage-location-ok",
@@ -76537,6 +76574,16 @@ var require_dist_Dwi4JA96 = __commonJS({
76537
76574
  powerState: zod.z.string().nullable(),
76538
76575
  saltLevel: DishwasherConsumableLevelSchema.nullable(),
76539
76576
  rinseAidLevel: DishwasherConsumableLevelSchema.nullable(),
76577
+ /**
76578
+ * True while the appliance asks for its filter to be cleaned (smart-filter, filter-system or
76579
+ * combined care-and-filter reminder raised); false when every such reminder reads clear; null
76580
+ * when none is reported. A cleared reminder is not an unknown one.
76581
+ */
76582
+ filterCleaningDue: zod.z.boolean().nullable(),
76583
+ /** True while the machine-care (descaling / cleaning-program) reminder is raised; false when clear; null when not reported. */
76584
+ machineCareDue: zod.z.boolean().nullable(),
76585
+ /** Program runs left before the machine-care reminder is due; null when the appliance does not say. */
76586
+ machineCareRemainingRuns: zod.z.number().int().nonnegative().nullable(),
76540
76587
  /** Option states: null when the appliance does not expose the option or has not said. */
76541
76588
  halfLoad: zod.z.boolean().nullable(),
76542
76589
  hygienePlus: zod.z.boolean().nullable(),
@@ -84663,16 +84710,6 @@ var require_dist_Dwi4JA96 = __commonJS({
84663
84710
  allowedDevices: zod.z.record(zod.z.string(), zod.z.union([zod.z.array(zod.z.string()), zod.z.literal("*")])).optional(),
84664
84711
  scopes: zod.z.array(TokenScopeSchema).optional()
84665
84712
  });
84666
- var ApiKeySummarySchema = zod.z.object({
84667
- id: zod.z.string(),
84668
- label: zod.z.string(),
84669
- isAdmin: zod.z.boolean().default(false),
84670
- allowedProviders: zod.z.union([zod.z.array(zod.z.string()), zod.z.literal("*")]).optional(),
84671
- allowedDevices: zod.z.record(zod.z.string(), zod.z.union([zod.z.array(zod.z.string()), zod.z.literal("*")])).optional(),
84672
- tokenPrefix: zod.z.string(),
84673
- createdAt: zod.z.number(),
84674
- lastUsedAt: zod.z.number().optional()
84675
- });
84676
84713
  var OauthSessionSummarySchema = zod.z.object({
84677
84714
  id: zod.z.string(),
84678
84715
  userId: zod.z.string(),
@@ -84753,12 +84790,6 @@ var require_dist_Dwi4JA96 = __commonJS({
84753
84790
  kind: "mutation",
84754
84791
  access: "view"
84755
84792
  }),
84756
- listApiKeys: method(zod.z.void(), zod.z.array(ApiKeySummarySchema), { auth: "admin" }),
84757
- revokeApiKey: method(zod.z.object({ id: zod.z.string() }), zod.z.object({ success: zod.z.literal(true) }), {
84758
- kind: "mutation",
84759
- auth: "admin",
84760
- access: "delete"
84761
- }),
84762
84793
  setupTotp: method(zod.z.object({ userId: zod.z.string() }), TotpSetupResultSchema, {
84763
84794
  kind: "mutation",
84764
84795
  auth: "admin",
@@ -94106,6 +94137,12 @@ var require_dist_Dwi4JA96 = __commonJS({
94106
94137
  addonId: null,
94107
94138
  access: "view"
94108
94139
  },
94140
+ "records.transact": {
94141
+ capName: "records",
94142
+ capScope: "system",
94143
+ addonId: null,
94144
+ access: "create"
94145
+ },
94109
94146
  "sceneMonitor.captureReference": {
94110
94147
  capName: "scene-monitor",
94111
94148
  capScope: "device",
@@ -95438,12 +95475,6 @@ var require_dist_Dwi4JA96 = __commonJS({
95438
95475
  addonId: null,
95439
95476
  access: "view"
95440
95477
  },
95441
- "userManagement.listApiKeys": {
95442
- capName: "user-management",
95443
- capScope: "system",
95444
- addonId: null,
95445
- access: "view"
95446
- },
95447
95478
  "userManagement.listExternalIdentities": {
95448
95479
  capName: "user-management",
95449
95480
  capScope: "system",
@@ -95498,12 +95529,6 @@ var require_dist_Dwi4JA96 = __commonJS({
95498
95529
  addonId: null,
95499
95530
  access: "create"
95500
95531
  },
95501
- "userManagement.revokeApiKey": {
95502
- capName: "user-management",
95503
- capScope: "system",
95504
- addonId: null,
95505
- access: "delete"
95506
- },
95507
95532
  "userManagement.revokeOauthSession": {
95508
95533
  capName: "user-management",
95509
95534
  capScope: "system",
@@ -99702,9 +99727,13 @@ var require_dist_Dwi4JA96 = __commonJS({
99702
99727
  "stream-online": "device-events",
99703
99728
  "stream-offline": "device-events",
99704
99729
  "detection-blind": "device-events",
99730
+ "motion-noisy": "device-events",
99731
+ "motion-calm": "device-events",
99705
99732
  "recording-stalled": "device-events",
99706
99733
  "recording-healthy": "device-events",
99707
99734
  "recording-degraded": "device-events",
99735
+ "device-attention-required": "device-events",
99736
+ "device-attention-resolved": "device-events",
99708
99737
  "node-online": "system",
99709
99738
  "node-offline": "system",
99710
99739
  "node-restarting": "system",
@@ -99787,6 +99816,12 @@ var require_dist_Dwi4JA96 = __commonJS({
99787
99816
  label: "Detecting nothing",
99788
99817
  kinds: ["detection-blind"]
99789
99818
  },
99819
+ {
99820
+ id: "motion-noise",
99821
+ family: "device-events",
99822
+ label: "Motion without a subject",
99823
+ kinds: ["motion-noisy", "motion-calm"]
99824
+ },
99790
99825
  {
99791
99826
  id: "recording",
99792
99827
  family: "device-events",
@@ -99797,6 +99832,12 @@ var require_dist_Dwi4JA96 = __commonJS({
99797
99832
  "recording-degraded"
99798
99833
  ]
99799
99834
  },
99835
+ {
99836
+ id: "device-attention",
99837
+ family: "device-events",
99838
+ label: "Needs attention",
99839
+ kinds: ["device-attention-required", "device-attention-resolved"]
99840
+ },
99800
99841
  {
99801
99842
  id: "nodes",
99802
99843
  family: "system",
@@ -99948,6 +99989,7 @@ var require_dist_Dwi4JA96 = __commonJS({
99948
99989
  "alert-error",
99949
99990
  "alert-critical-resolved"
99950
99991
  ];
99992
+ var DEVICE_ATTENTION = ["device-attention-required", "device-attention-resolved"];
99951
99993
  var UPDATES = [
99952
99994
  "addon-update-available",
99953
99995
  "server-update-available",
@@ -99977,9 +100019,12 @@ var require_dist_Dwi4JA96 = __commonJS({
99977
100019
  "stream-online",
99978
100020
  "stream-offline",
99979
100021
  "detection-blind",
100022
+ "motion-noisy",
100023
+ "motion-calm",
99980
100024
  "recording-stalled",
99981
100025
  "recording-healthy",
99982
100026
  "recording-degraded",
100027
+ ...DEVICE_ATTENTION,
99983
100028
  ...ALARM
99984
100029
  ];
99985
100030
  var SUMMARISABLE = [...systemEventKindsOfFamily("device-events"), ...systemEventKindsOfFamily("system")];
@@ -100144,7 +100189,9 @@ var require_dist_Dwi4JA96 = __commonJS({
100144
100189
  [...RULE_TEXT],
100145
100190
  [...RULE_TEXT],
100146
100191
  [...RULE_TEXT],
100147
- ([...RULE_TEXT], [...ALERT_EPISODE]),
100192
+ [...RULE_TEXT],
100193
+ [...RULE_TEXT],
100194
+ ([...RULE_TEXT], [...DEVICE_ATTENTION, ...ALERT_EPISODE]),
100148
100195
  [...RULE_TEXT],
100149
100196
  [...RULE_TEXT],
100150
100197
  [...RULE_TEXT],
@@ -100166,11 +100213,11 @@ var require_dist_Dwi4JA96 = __commonJS({
100166
100213
  [...RULE_TEXT],
100167
100214
  [...RULE_TEXT],
100168
100215
  [...RULE_TEXT],
100216
+ ([...RULE_TEXT], [...DEVICE_ATTENTION, ...ALERT_EPISODE]),
100169
100217
  ([...RULE_TEXT], [...ALERT_EPISODE]),
100218
+ ([...RULE_TEXT], [...DEVICE_ATTENTION, ...ALERT_EPISODE]),
100170
100219
  ([...RULE_TEXT], [...ALERT_EPISODE]),
100171
- ([...RULE_TEXT], [...ALERT_EPISODE]),
100172
- ([...RULE_TEXT], [...ALERT_EPISODE]),
100173
- ([...RULE_TEXT], [...ALERT_EPISODE]),
100220
+ ([...RULE_TEXT], [...DEVICE_ATTENTION, ...ALERT_EPISODE]),
100174
100221
  [...RULE_TEXT],
100175
100222
  [...RULE_TEXT],
100176
100223
  [...RULE_TEXT],
@@ -100246,6 +100293,15 @@ var require_dist_Dwi4JA96 = __commonJS({
100246
100293
  snapshotLabel: "Tanks low or full now",
100247
100294
  snapshotSection: "tanks"
100248
100295
  },
100296
+ {
100297
+ id: "motion-noise",
100298
+ family: "device-events",
100299
+ label: "Motion without a subject (constant / calm again)",
100300
+ bad: ["motion-noisy"],
100301
+ recovery: ["motion-calm"],
100302
+ snapshotLabel: "Cameras with constant motion now",
100303
+ snapshotSection: null
100304
+ },
100249
100305
  {
100250
100306
  id: "recording-health",
100251
100307
  family: "device-events",
@@ -100255,6 +100311,15 @@ var require_dist_Dwi4JA96 = __commonJS({
100255
100311
  snapshotLabel: "Recordings stalled now",
100256
100312
  snapshotSection: null
100257
100313
  },
100314
+ {
100315
+ id: "device-attention",
100316
+ family: "device-events",
100317
+ label: "Device needs attention (raised / resolved)",
100318
+ bad: ["device-attention-required"],
100319
+ recovery: ["device-attention-resolved"],
100320
+ snapshotLabel: "Devices needing attention now",
100321
+ snapshotSection: null
100322
+ },
100258
100323
  {
100259
100324
  id: "node-connectivity",
100260
100325
  family: "system",
@@ -100899,12 +100964,6 @@ var require_dist_Dwi4JA96 = __commonJS({
100899
100964
  return AlertSchema;
100900
100965
  }
100901
100966
  });
100902
- Object.defineProperty(exports, "ApiKeyRecordSchema", {
100903
- enumerable: true,
100904
- get: function() {
100905
- return ApiKeyRecordSchema;
100906
- }
100907
- });
100908
100967
  Object.defineProperty(exports, "BaseAddon", {
100909
100968
  enumerable: true,
100910
100969
  get: function() {
@@ -101475,12 +101534,24 @@ var require_dist_Dwi4JA96 = __commonJS({
101475
101534
  return StorageMigrationJobSchema;
101476
101535
  }
101477
101536
  });
101537
+ Object.defineProperty(exports, "StoredRecordKindDeclarationSchema", {
101538
+ enumerable: true,
101539
+ get: function() {
101540
+ return StoredRecordKindDeclarationSchema;
101541
+ }
101542
+ });
101478
101543
  Object.defineProperty(exports, "TokenScopeSchema", {
101479
101544
  enumerable: true,
101480
101545
  get: function() {
101481
101546
  return TokenScopeSchema;
101482
101547
  }
101483
101548
  });
101549
+ Object.defineProperty(exports, "TransactRefusedError", {
101550
+ enumerable: true,
101551
+ get: function() {
101552
+ return TransactRefusedError;
101553
+ }
101554
+ });
101484
101555
  Object.defineProperty(exports, "UNATTRIBUTED_BUCKET_KEY", {
101485
101556
  enumerable: true,
101486
101557
  get: function() {
@@ -101571,6 +101642,12 @@ var require_dist_Dwi4JA96 = __commonJS({
101571
101642
  return asString$1;
101572
101643
  }
101573
101644
  });
101645
+ Object.defineProperty(exports, "assertTransactScope", {
101646
+ enumerable: true,
101647
+ get: function() {
101648
+ return assertTransactScope;
101649
+ }
101650
+ });
101574
101651
  Object.defineProperty(exports, "assertValidDeclaration", {
101575
101652
  enumerable: true,
101576
101653
  get: function() {
@@ -102636,40 +102713,6 @@ var require_dist_Dwi4JA96 = __commonJS({
102636
102713
  }
102637
102714
  });
102638
102715
 
102639
- // ../system/dist/read-all-rows-CVoO1ONM.js
102640
- var require_read_all_rows_CVoO1ONM = __commonJS({
102641
- "../system/dist/read-all-rows-CVoO1ONM.js"(exports) {
102642
- "use strict";
102643
- var require_read_all_rows = /* @__PURE__ */ require_chunk_Cek0wNdY().__commonJSMin(((exports2) => {
102644
- Object.defineProperty(exports2, "__esModule", { value: true });
102645
- exports2.readAllRows = readAllRows;
102646
- var PAGE_SIZE = 1e3;
102647
- var MAX_PAGES = 100;
102648
- async function readAllRows(kind, query = {}, options = {}) {
102649
- const out = [];
102650
- let cursor;
102651
- for (let page = 0; page < MAX_PAGES; page += 1) {
102652
- const answer = await kind.query({
102653
- ...query,
102654
- limit: PAGE_SIZE,
102655
- ...cursor === void 0 ? {} : { cursor }
102656
- }, options);
102657
- out.push(...answer.records);
102658
- if (answer.nextCursor === null) return out;
102659
- cursor = answer.nextCursor;
102660
- }
102661
- throw new Error(`record kind "${kind.name}" holds more than ${MAX_PAGES * PAGE_SIZE} rows`);
102662
- }
102663
- }));
102664
- Object.defineProperty(exports, "require_read_all_rows", {
102665
- enumerable: true,
102666
- get: function() {
102667
- return require_read_all_rows;
102668
- }
102669
- });
102670
- }
102671
- });
102672
-
102673
102716
  // ../system/dist/x509.es-C4cOo48M.js
102674
102717
  var require_x509_es_C4cOo48M = __commonJS({
102675
102718
  "../system/dist/x509.es-C4cOo48M.js"(exports) {
@@ -114141,11 +114184,11 @@ ${values.join("\n")}` : `${blockName} :`;
114141
114184
  }
114142
114185
  });
114143
114186
 
114144
- // ../system/dist/device-ca-B-Txwl4W.js
114145
- var require_device_ca_B_Txwl4W = __commonJS({
114146
- "../system/dist/device-ca-B-Txwl4W.js"(exports) {
114187
+ // ../system/dist/device-ca-DpvQ5wrb.js
114188
+ var require_device_ca_DpvQ5wrb = __commonJS({
114189
+ "../system/dist/device-ca-DpvQ5wrb.js"(exports) {
114147
114190
  "use strict";
114148
- var require_dist10 = require_dist_Dwi4JA96();
114191
+ var require_dist10 = require_dist_QyW9hVO2();
114149
114192
  var require_x509_es = require_x509_es_C4cOo48M();
114150
114193
  var node_crypto = __require("crypto");
114151
114194
  var SYSTEM_SECRET_OWNER = "system";
@@ -114560,6 +114603,40 @@ var require_device_ca_B_Txwl4W = __commonJS({
114560
114603
  }
114561
114604
  });
114562
114605
 
114606
+ // ../system/dist/read-all-rows-CVoO1ONM.js
114607
+ var require_read_all_rows_CVoO1ONM = __commonJS({
114608
+ "../system/dist/read-all-rows-CVoO1ONM.js"(exports) {
114609
+ "use strict";
114610
+ var require_read_all_rows = /* @__PURE__ */ require_chunk_Cek0wNdY().__commonJSMin(((exports2) => {
114611
+ Object.defineProperty(exports2, "__esModule", { value: true });
114612
+ exports2.readAllRows = readAllRows;
114613
+ var PAGE_SIZE = 1e3;
114614
+ var MAX_PAGES = 100;
114615
+ async function readAllRows(kind, query = {}, options = {}) {
114616
+ const out = [];
114617
+ let cursor;
114618
+ for (let page = 0; page < MAX_PAGES; page += 1) {
114619
+ const answer = await kind.query({
114620
+ ...query,
114621
+ limit: PAGE_SIZE,
114622
+ ...cursor === void 0 ? {} : { cursor }
114623
+ }, options);
114624
+ out.push(...answer.records);
114625
+ if (answer.nextCursor === null) return out;
114626
+ cursor = answer.nextCursor;
114627
+ }
114628
+ throw new Error(`record kind "${kind.name}" holds more than ${MAX_PAGES * PAGE_SIZE} rows`);
114629
+ }
114630
+ }));
114631
+ Object.defineProperty(exports, "require_read_all_rows", {
114632
+ enumerable: true,
114633
+ get: function() {
114634
+ return require_read_all_rows;
114635
+ }
114636
+ });
114637
+ }
114638
+ });
114639
+
114563
114640
  // ../system/dist/builtins/alerts/alerts.addon.js
114564
114641
  var require_alerts_addon = __commonJS({
114565
114642
  "../system/dist/builtins/alerts/alerts.addon.js"(exports) {
@@ -114569,7 +114646,7 @@ var require_alerts_addon = __commonJS({
114569
114646
  [Symbol.toStringTag]: { value: "Module" }
114570
114647
  });
114571
114648
  require_chunk_Cek0wNdY();
114572
- var require_dist10 = require_dist_Dwi4JA96();
114649
+ var require_dist10 = require_dist_QyW9hVO2();
114573
114650
  var require_read_all_rows$1 = require_read_all_rows_CVoO1ONM();
114574
114651
  function nextEpisodeId(input) {
114575
114652
  const { previous } = input;
@@ -116037,7 +116114,7 @@ var require_calendars_addon = __commonJS({
116037
116114
  [Symbol.toStringTag]: { value: "Module" }
116038
116115
  });
116039
116116
  require_chunk_Cek0wNdY();
116040
- var require_dist10 = require_dist_Dwi4JA96();
116117
+ var require_dist10 = require_dist_QyW9hVO2();
116041
116118
  var require_settle_sources = require_settle_sources_Bhsy57y();
116042
116119
  var zod = require_zod();
116043
116120
  var CALENDAR_COLOR_PALETTE = [
@@ -116253,11 +116330,11 @@ var require_calendars = __commonJS({
116253
116330
  }
116254
116331
  });
116255
116332
 
116256
- // ../system/dist/composition-sources-BG0E76VO.js
116257
- var require_composition_sources_BG0E76VO = __commonJS({
116258
- "../system/dist/composition-sources-BG0E76VO.js"(exports) {
116333
+ // ../system/dist/composition-sources-DqHwltDV.js
116334
+ var require_composition_sources_DqHwltDV = __commonJS({
116335
+ "../system/dist/composition-sources-DqHwltDV.js"(exports) {
116259
116336
  "use strict";
116260
- var require_dist10 = require_dist_Dwi4JA96();
116337
+ var require_dist10 = require_dist_QyW9hVO2();
116261
116338
  function normalizedNativeOwner(owner) {
116262
116339
  const trimmed = owner?.trim();
116263
116340
  return trimmed ? trimmed : null;
@@ -116372,8 +116449,8 @@ var require_composer_addon = __commonJS({
116372
116449
  [Symbol.toStringTag]: { value: "Module" }
116373
116450
  });
116374
116451
  require_chunk_Cek0wNdY();
116375
- var require_dist10 = require_dist_Dwi4JA96();
116376
- var require_composition_sources = require_composition_sources_BG0E76VO();
116452
+ var require_dist10 = require_dist_QyW9hVO2();
116453
+ var require_composition_sources = require_composition_sources_DqHwltDV();
116377
116454
  var zod = require_zod();
116378
116455
  function isRecord$2(value) {
116379
116456
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -120183,7 +120260,7 @@ var require_console_logging = __commonJS({
120183
120260
  [Symbol.toStringTag]: { value: "Module" }
120184
120261
  });
120185
120262
  require_chunk_Cek0wNdY();
120186
- var require_dist10 = require_dist_Dwi4JA96();
120263
+ var require_dist10 = require_dist_QyW9hVO2();
120187
120264
  var require_formatter = require_formatter_DqAKDlvN();
120188
120265
  var LEVEL_RANK = {
120189
120266
  debug: 0,
@@ -124847,9 +124924,9 @@ var require_core_blocks_addon = __commonJS({
124847
124924
  "use strict";
124848
124925
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
124849
124926
  var require_chunk = require_chunk_Cek0wNdY();
124850
- var require_dist10 = require_dist_Dwi4JA96();
124927
+ var require_dist10 = require_dist_QyW9hVO2();
124851
124928
  var require_read_all_rows$1 = require_read_all_rows_CVoO1ONM();
124852
- var require_composition_sources = require_composition_sources_BG0E76VO();
124929
+ var require_composition_sources = require_composition_sources_DqHwltDV();
124853
124930
  var require_prefix_range = require_prefix_range_D_KueXbQ();
124854
124931
  var require_prefix_walk = require_prefix_walk_Dv6MLZlM();
124855
124932
  var zod = require_zod();
@@ -127047,9 +127124,9 @@ var require_core_blocks = __commonJS({
127047
127124
  }
127048
127125
  });
127049
127126
 
127050
- // ../types/dist/event-category-kpu1bZMs.js
127051
- var require_event_category_kpu1bZMs = __commonJS({
127052
- "../types/dist/event-category-kpu1bZMs.js"(exports) {
127127
+ // ../types/dist/event-category-7AwNbPjm.js
127128
+ var require_event_category_7AwNbPjm = __commonJS({
127129
+ "../types/dist/event-category-7AwNbPjm.js"(exports) {
127053
127130
  "use strict";
127054
127131
  var EventCategory = /* @__PURE__ */ (function(EventCategory2) {
127055
127132
  EventCategory2["SystemBoot"] = "system.boot";
@@ -127131,6 +127208,8 @@ var require_event_category_kpu1bZMs = __commonJS({
127131
127208
  EventCategory2["PipelineCameraUnassigned"] = "pipeline.camera-unassigned";
127132
127209
  EventCategory2["PipelineNodeInferenceUnavailable"] = "pipeline.node-inference-unavailable";
127133
127210
  EventCategory2["PipelineDetectionBlind"] = "pipeline.detection-blind";
127211
+ EventCategory2["PipelineMotionNoisy"] = "pipeline.motion-noisy";
127212
+ EventCategory2["PipelineMotionCalm"] = "pipeline.motion-calm";
127134
127213
  EventCategory2["PipelineCameraUpdated"] = "pipeline.camera-updated";
127135
127214
  EventCategory2["PipelineIngestOwnerChanged"] = "pipeline.ingest-owner-changed";
127136
127215
  EventCategory2["PipelineRunnerLoadSnapshot"] = "pipeline.runner-load-snapshot";
@@ -127254,11 +127333,11 @@ var require_event_category_kpu1bZMs = __commonJS({
127254
127333
  }
127255
127334
  });
127256
127335
 
127257
- // ../types/dist/sleep-Bo7fq491.js
127258
- var require_sleep_Bo7fq491 = __commonJS({
127259
- "../types/dist/sleep-Bo7fq491.js"(exports) {
127336
+ // ../types/dist/sleep-CD18m9HF.js
127337
+ var require_sleep_CD18m9HF = __commonJS({
127338
+ "../types/dist/sleep-CD18m9HF.js"(exports) {
127260
127339
  "use strict";
127261
- var require_event_category = require_event_category_kpu1bZMs();
127340
+ var require_event_category = require_event_category_7AwNbPjm();
127262
127341
  var zod = require_zod();
127263
127342
  var AUDIO_CHUNK_FORMATS = [
127264
127343
  "f32le",
@@ -129936,7 +130015,8 @@ var require_sleep_Bo7fq491 = __commonJS({
129936
130015
  "invalid-record",
129937
130016
  "declaration-refused",
129938
130017
  "no-caller",
129939
- "batch-too-large"
130018
+ "batch-too-large",
130019
+ "transact-refused"
129940
130020
  ];
129941
130021
  var PREFIX = "records/";
129942
130022
  var RecordsError = class extends Error {
@@ -130033,6 +130113,12 @@ var require_sleep_Bo7fq491 = __commonJS({
130033
130113
  this.name = "BatchTooLargeError";
130034
130114
  }
130035
130115
  };
130116
+ var TransactRefusedError = class extends RecordsError {
130117
+ constructor(detail) {
130118
+ super("transact-refused", detail);
130119
+ this.name = "TransactRefusedError";
130120
+ }
130121
+ };
130036
130122
  var FACTORIES = {
130037
130123
  "rev-conflict": (d) => new RevConflictError(d),
130038
130124
  "too-large": (d) => new RecordTooLargeError(d),
@@ -130047,7 +130133,8 @@ var require_sleep_Bo7fq491 = __commonJS({
130047
130133
  "invalid-record": (d) => new InvalidRecordError(d),
130048
130134
  "declaration-refused": (d) => new DeclarationRefusedError(d),
130049
130135
  "no-caller": (d) => new NoCallerError(d),
130050
- "batch-too-large": (d) => new BatchTooLargeError(d)
130136
+ "batch-too-large": (d) => new BatchTooLargeError(d),
130137
+ "transact-refused": (d) => new TransactRefusedError(d)
130051
130138
  };
130052
130139
  function isCode(value) {
130053
130140
  return RECORDS_ERROR_CODES.some((code) => code === value);
@@ -130250,7 +130337,7 @@ var require_sleep_Bo7fq491 = __commonJS({
130250
130337
  /** JSON Schema of the entry body; `secret: true` marks a password field. */
130251
130338
  fields: zod.z.record(zod.z.string(), zod.z.unknown())
130252
130339
  }).strict();
130253
- var RecordKindDeclarationSchema = zod.z.object({
130340
+ var RecordKindDeclarationShape = zod.z.object({
130254
130341
  database: zod.z.enum(RECORD_DATABASES).default("settings"),
130255
130342
  class: zod.z.enum(RECORD_CLASSES),
130256
130343
  writeTrigger: zod.z.string().min(1),
@@ -130268,18 +130355,12 @@ var require_sleep_Bo7fq491 = __commonJS({
130268
130355
  secretPaths: zod.z.array(zod.z.string().min(1)).default([]),
130269
130356
  /** The id key of each array that carries a secret (`{ headers: 'name' }`). */
130270
130357
  secretArrayKeys: zod.z.record(zod.z.string(), zod.z.string()).default({}),
130271
- /**
130272
- * RETIRED (D900): the legacy table a kind adopted from during the records
130273
- * migration. Nothing declares it any more and nothing reads it; the schema
130274
- * still ACCEPTS it because the catalog rows the migration wrote carry it
130275
- * (an orphaned kind is never redeclared) and an addon built before the
130276
- * removal still sends it. Never set it.
130277
- */
130278
- adoptsFrom: zod.z.string().min(1).optional(),
130279
130358
  /** Kinds that must agree through `transact` sit in one file under one family name. */
130280
130359
  transactFamily: zod.z.string().min(1).optional(),
130281
130360
  entry: EntryDescriptorSchema.optional()
130282
- }).strict();
130361
+ });
130362
+ var RecordKindDeclarationSchema = RecordKindDeclarationShape.strict();
130363
+ var StoredRecordKindDeclarationSchema = RecordKindDeclarationShape;
130283
130364
  var RecordKindNameSchema = zod.z.string().regex(/^[a-z][a-z0-9-]{0,47}$/);
130284
130365
  function assertValidDeclaration(name, decl) {
130285
130366
  const refuse = (why) => {
@@ -130360,6 +130441,16 @@ var require_sleep_Bo7fq491 = __commonJS({
130360
130441
  function declarationsOf(kinds) {
130361
130442
  return Object.fromEntries(Object.entries(kinds).map(([name, kind]) => [name, kind.declaration]));
130362
130443
  }
130444
+ function assertTransactScope(members) {
130445
+ const byKind = /* @__PURE__ */ new Map();
130446
+ for (const m of members) byKind.set(m.kind, m);
130447
+ const kinds = [...byKind.values()];
130448
+ if (new Set(kinds.map((m) => m.declaration.database)).size > 1) throw new TransactRefusedError(`cross-file: the ops span more than one database file (${kinds.map((m) => `${m.kind}@${m.declaration.database}`).join(", ")}); a transaction lives in ONE file`);
130449
+ if (kinds.length <= 1) return;
130450
+ const missing = kinds.filter((m) => m.declaration.transactFamily === void 0);
130451
+ if (missing.length > 0) throw new TransactRefusedError(`no-family: ${missing.map((m) => m.kind).join(", ")} declare no transactFamily; kinds that must agree through transact share one`);
130452
+ if (new Set(kinds.map((m) => m.declaration.transactFamily)).size > 1) throw new TransactRefusedError(`cross-family: the ops span more than one transactFamily (${kinds.map((m) => `${m.kind}=${String(m.declaration.transactFamily)}`).join(", ")})`);
130453
+ }
130363
130454
  function isRecord$2(value) {
130364
130455
  return typeof value === "object" && value !== null && !Array.isArray(value);
130365
130456
  }
@@ -130533,6 +130624,48 @@ var require_sleep_Bo7fq491 = __commonJS({
130533
130624
  };
130534
130625
  });
130535
130626
  }
130627
+ async txPut(input, opts = {}) {
130628
+ const checked = this.validate(input.data, input.id);
130629
+ const { body, rollback } = await this.storeSecrets(input.id, checked, "put");
130630
+ return {
130631
+ wire: {
130632
+ op: "put",
130633
+ kind: this.name,
130634
+ record: {
130635
+ ...input,
130636
+ data: toBody(body)
130637
+ },
130638
+ ...opts.ifRev === void 0 ? {} : { ifRev: opts.ifRev }
130639
+ },
130640
+ rollback
130641
+ };
130642
+ }
130643
+ async txPatch(id, partial, opts = {}) {
130644
+ const { body, rollback } = await this.storeSecrets(id, partial, "patch");
130645
+ return {
130646
+ wire: {
130647
+ op: "patch",
130648
+ kind: this.name,
130649
+ id,
130650
+ data: toBody(body),
130651
+ ...opts.at === void 0 ? {} : { at: opts.at },
130652
+ ...opts.expiresAt === void 0 ? {} : { expiresAt: opts.expiresAt },
130653
+ ...opts.ifRev === void 0 ? {} : { ifRev: opts.ifRev }
130654
+ },
130655
+ rollback
130656
+ };
130657
+ }
130658
+ txDelete(id) {
130659
+ return {
130660
+ wire: {
130661
+ op: "delete",
130662
+ kind: this.name,
130663
+ id
130664
+ },
130665
+ rollback: async () => {
130666
+ }
130667
+ };
130668
+ }
130536
130669
  async put(input, opts = {}) {
130537
130670
  const checked = this.validate(input.data, input.id);
130538
130671
  const { body, rollback } = await this.storeSecrets(input.id, checked, "put");
@@ -130686,6 +130819,23 @@ var require_sleep_Bo7fq491 = __commonJS({
130686
130819
  handles.set(definition, handle);
130687
130820
  return handle;
130688
130821
  },
130822
+ async transact(ops) {
130823
+ if (ops.length === 0) return [];
130824
+ const result = await call(() => options.transport.transact({ ops: ops.map((op) => op.wire) })).catch(async (err) => {
130825
+ for (const op of ops) await op.rollback();
130826
+ throw err;
130827
+ });
130828
+ const released = [...result.releasedRefs, ...result.secretRefs];
130829
+ if (released.length > 0 && options.secrets !== null) try {
130830
+ await options.secrets.delete(released);
130831
+ } catch (err) {
130832
+ options.logger?.warn("records: could not remove released keychain values", { meta: {
130833
+ count: released.length,
130834
+ error: err instanceof Error ? err.message : "unknown"
130835
+ } });
130836
+ }
130837
+ return result.results;
130838
+ },
130689
130839
  async deleteDevice(deviceId, opts = {}) {
130690
130840
  const result = await call(() => options.transport.deleteDevice({
130691
130841
  deviceId,
@@ -131177,312 +131327,372 @@ var require_sleep_Bo7fq491 = __commonJS({
131177
131327
  secretRefs: refsOf(decl, gone)
131178
131328
  };
131179
131329
  };
131180
- return {
131181
- records: createRecordsAccess({
131182
- owner,
131183
- transport: {
131184
- declareKinds: async ({ kinds }) => {
131185
- const out = {};
131186
- for (const [name, raw] of Object.entries(kinds)) {
131187
- const decl = RecordKindDeclarationSchema.parse(raw);
131188
- assertValidDeclaration(name, decl);
131189
- const prior = decls.get(name);
131190
- if (prior !== void 0) assertAdditive(name, prior, decl);
131191
- const kindId = kindIds.get(name) ?? kindIds.size + 1;
131192
- kindIds.set(name, kindId);
131193
- const created = decl.indexes.filter((i) => prior?.indexes.every((p) => p.name !== i.name) ?? true).map((i) => i.name);
131194
- const state = prior === void 0 ? "created" : JSON.stringify(prior) === JSON.stringify(decl) ? "unchanged" : "updated";
131195
- decls.set(name, decl);
131196
- out[name] = {
131197
- kindId,
131198
- state,
131199
- createdIndexes: created,
131200
- adoptionPending: null
131201
- };
131202
- }
131203
- return { kinds: out };
131204
- },
131205
- get: async ({ kind, id }) => {
131206
- reading();
131207
- const decl = declOf(kind);
131208
- const row = table(kind).get(id);
131209
- return row === void 0 ? null : view(decl, row);
131210
- },
131211
- getMany: async ({ kind, ids }) => {
131212
- reading();
131213
- const decl = declOf(kind);
131214
- return [...new Set(ids)].sort((a, b) => compareSql(a, b)).flatMap((id) => {
131215
- const row = table(kind).get(id);
131216
- return row === void 0 ? [] : [view(decl, row)];
131217
- });
131218
- },
131219
- secretRefs: async ({ kind, ids }) => {
131220
- reading();
131221
- const decl = declOf(kind);
131222
- const out = {};
131223
- for (const id of ids) {
131224
- const row = table(kind).get(id);
131225
- if (row === void 0) continue;
131226
- const refs = Object.fromEntries(markersOf(decl, row.data));
131227
- if (Object.keys(refs).length > 0) out[id] = refs;
131228
- }
131229
- return out;
131230
- },
131231
- put: async ({ kind, record, ifRev }) => {
131232
- writing();
131233
- const written = writeRecord(kind, record, ifRev, now());
131234
- afterWrite(kind, [record.deviceId]);
131235
- return {
131236
- rev: written.rev,
131237
- releasedRefs: [...written.released]
131238
- };
131239
- },
131240
- putMany: async ({ kind, records }) => {
131241
- writing();
131242
- declOf(kind);
131243
- if (records.length > 1e3) throw new BatchTooLargeError(`${records.length} records exceed ${RECORD_BATCH_MAX}`);
131244
- const bytes = records.reduce((sum, r) => sum + Buffer.byteLength(JSON.stringify(r.data), "utf8"), 0);
131245
- if (bytes > 4194304) throw new BatchTooLargeError(`${bytes} bytes exceed ${RECORD_BATCH_MAX_BYTES}`);
131246
- const nowMs = now();
131247
- const before = new Map(table(kind));
131248
- const ridBefore = nextRid;
131249
- const released = [];
131250
- try {
131251
- for (const rec of records) released.push(...writeRecord(kind, rec, void 0, nowMs).released);
131252
- } catch (err) {
131253
- tables.set(kind, before);
131254
- nextRid = ridBefore;
131255
- throw err;
131330
+ const transport = {
131331
+ declareKinds: async ({ kinds }) => {
131332
+ const out = {};
131333
+ for (const [name, raw] of Object.entries(kinds)) {
131334
+ const decl = RecordKindDeclarationSchema.parse(raw);
131335
+ assertValidDeclaration(name, decl);
131336
+ const prior = decls.get(name);
131337
+ if (prior !== void 0) assertAdditive(name, prior, decl);
131338
+ const kindId = kindIds.get(name) ?? kindIds.size + 1;
131339
+ kindIds.set(name, kindId);
131340
+ const created = decl.indexes.filter((i) => prior?.indexes.every((p) => p.name !== i.name) ?? true).map((i) => i.name);
131341
+ const state = prior === void 0 ? "created" : JSON.stringify(prior) === JSON.stringify(decl) ? "unchanged" : "updated";
131342
+ decls.set(name, decl);
131343
+ out[name] = {
131344
+ kindId,
131345
+ state,
131346
+ createdIndexes: created
131347
+ };
131348
+ }
131349
+ return { kinds: out };
131350
+ },
131351
+ get: async ({ kind, id }) => {
131352
+ reading();
131353
+ const decl = declOf(kind);
131354
+ const row = table(kind).get(id);
131355
+ return row === void 0 ? null : view(decl, row);
131356
+ },
131357
+ getMany: async ({ kind, ids }) => {
131358
+ reading();
131359
+ const decl = declOf(kind);
131360
+ return [...new Set(ids)].sort((a, b) => compareSql(a, b)).flatMap((id) => {
131361
+ const row = table(kind).get(id);
131362
+ return row === void 0 ? [] : [view(decl, row)];
131363
+ });
131364
+ },
131365
+ secretRefs: async ({ kind, ids }) => {
131366
+ reading();
131367
+ const decl = declOf(kind);
131368
+ const out = {};
131369
+ for (const id of ids) {
131370
+ const row = table(kind).get(id);
131371
+ if (row === void 0) continue;
131372
+ const refs = Object.fromEntries(markersOf(decl, row.data));
131373
+ if (Object.keys(refs).length > 0) out[id] = refs;
131374
+ }
131375
+ return out;
131376
+ },
131377
+ put: async ({ kind, record, ifRev }) => {
131378
+ writing();
131379
+ const written = writeRecord(kind, record, ifRev, now());
131380
+ afterWrite(kind, [record.deviceId]);
131381
+ return {
131382
+ rev: written.rev,
131383
+ releasedRefs: [...written.released]
131384
+ };
131385
+ },
131386
+ putMany: async ({ kind, records }) => {
131387
+ writing();
131388
+ declOf(kind);
131389
+ if (records.length > 1e3) throw new BatchTooLargeError(`${records.length} records exceed ${RECORD_BATCH_MAX}`);
131390
+ const bytes = records.reduce((sum, r) => sum + Buffer.byteLength(JSON.stringify(r.data), "utf8"), 0);
131391
+ if (bytes > 4194304) throw new BatchTooLargeError(`${bytes} bytes exceed ${RECORD_BATCH_MAX_BYTES}`);
131392
+ const nowMs = now();
131393
+ const before = new Map(table(kind));
131394
+ const ridBefore = nextRid;
131395
+ const released = [];
131396
+ try {
131397
+ for (const rec of records) released.push(...writeRecord(kind, rec, void 0, nowMs).released);
131398
+ } catch (err) {
131399
+ tables.set(kind, before);
131400
+ nextRid = ridBefore;
131401
+ throw err;
131402
+ }
131403
+ let top = -1;
131404
+ for (const r of records) if (/^\d{1,15}$/.test(r.id)) top = Math.max(top, Number(r.id));
131405
+ if (top >= 0) sequences.set(kind, Math.max(sequences.get(kind) ?? 0, top + 1));
131406
+ afterWrite(kind, records.map((r) => r.deviceId));
131407
+ return {
131408
+ count: records.length,
131409
+ releasedRefs: released
131410
+ };
131411
+ },
131412
+ patch: async (input) => {
131413
+ writing();
131414
+ const decl = declOf(input.kind);
131415
+ if (input.at !== void 0 && decl.at !== "required") throw new InvalidRecordError(`${input.kind}: declared at: "none"`);
131416
+ if (input.at === null) throw new InvalidRecordError(`${input.kind}: "at" cannot be removed`);
131417
+ if (input.expiresAt !== void 0 && decl.secretPaths.length > 0) throw new InvalidRecordError(`${input.kind}: a kind with secret fields cannot expire by the engine (its keychain values would be orphaned)`);
131418
+ if (input.expiresAt !== void 0 && "ttlMs" in decl.retention) throw new InvalidRecordError(`${input.kind}: expiresAt is set by the engine`);
131419
+ const before = table(input.kind).get(input.id);
131420
+ const checked = enforceSecrets(owner, input.kind, decl, input.id, input.data, before?.data ?? null, "patch");
131421
+ if (before === void 0) throw new RecordNotFoundError(`${input.kind}/${input.id}: no such row`);
131422
+ if (input.ifRev !== void 0 && before.rev !== input.ifRev) throw new RevConflictError(`${input.kind}/${input.id}: expected rev ${String(input.ifRev)}, found rev ${before.rev}`);
131423
+ const merged = jsonCopy(mergePatch(before.data, jsonCopy(checked.body)));
131424
+ const size = [...JSON.stringify(merged)].length;
131425
+ if (size > decl.maxDataBytes) throw new RecordTooLargeError(`${input.kind}/${input.id}: the patched body is ${size} bytes, over maxDataBytes ${decl.maxDataBytes}`);
131426
+ assertUnique(input.kind, decl, input.id, merged);
131427
+ const rev = before.rev + 1;
131428
+ store2(input.kind, before, {
131429
+ ...before,
131430
+ at: input.at ?? before.at,
131431
+ expiresAt: input.expiresAt === void 0 ? before.expiresAt : input.expiresAt,
131432
+ rev,
131433
+ updatedAt: now(),
131434
+ data: merged
131435
+ });
131436
+ const kept = new Set(markersOf(decl, merged).values());
131437
+ return {
131438
+ rev,
131439
+ releasedRefs: [...markersOf(decl, before.data).values()].filter((r) => !kept.has(r))
131440
+ };
131441
+ },
131442
+ delete: async ({ kind, id }) => {
131443
+ writing();
131444
+ const decl = declOf(kind);
131445
+ const row = table(kind).get(id);
131446
+ if (row === void 0) return {
131447
+ deleted: false,
131448
+ secretRefs: []
131449
+ };
131450
+ table(kind).delete(id);
131451
+ return {
131452
+ deleted: true,
131453
+ secretRefs: refsOf(decl, [row])
131454
+ };
131455
+ },
131456
+ deleteMany: async ({ kind, ids }) => {
131457
+ writing();
131458
+ const wanted = new Set(ids);
131459
+ return removeWhere(kind, (row) => wanted.has(row.id));
131460
+ },
131461
+ query: async (q) => {
131462
+ reading();
131463
+ const decl = declOf(q.kind);
131464
+ queries.push({
131465
+ kind: q.kind,
131466
+ limit: q.limit
131467
+ });
131468
+ assertWindowAllowed(q.kind, decl, q);
131469
+ const desc = q.desc === true;
131470
+ const dir = desc ? "DESC" : "ASC";
131471
+ const where = planWhere(q.kind, decl, q.where, { allowIn: false });
131472
+ const cursor = q.cursor === void 0 ? void 0 : decodeCursor(q.cursor);
131473
+ let rows = [...table(q.kind).values()].filter((r) => inWindow(r, q));
131474
+ let keysOf;
131475
+ let keyCount;
131476
+ let tag;
131477
+ if (where !== null) {
131478
+ if (q.order !== void 0) throw new InvalidRecordError(`${q.kind}: with a where the order is the index's; drop "order"`);
131479
+ const fields = where.orderFields;
131480
+ keysOf = (row) => [...fields.map((f) => extractField(row.data, f)), row.rid];
131481
+ keyCount = fields.length;
131482
+ tag = `rx:${where.indexName}:${dir}`;
131483
+ rows = rows.filter((r) => where.matches(r.data));
131484
+ if (cursor !== void 0) {
131485
+ assertCursor(cursor, tag, fields.length + 1);
131486
+ rows = rows.filter((r) => rowValueAfter(keysOf(r), cursor.values, desc));
131487
+ }
131488
+ } else {
131489
+ const order = q.order ?? (decl.at === "required" ? "at" : "id");
131490
+ keyCount = 1;
131491
+ if (order === "at") {
131492
+ if (decl.at !== "required") throw new InvalidRecordError(`${q.kind}: declared at: "none", it has no time order - use order: "id"`);
131493
+ keysOf = (row) => [row.at, row.rid];
131494
+ tag = `at:${dir}`;
131495
+ if (cursor !== void 0) {
131496
+ assertCursor(cursor, tag, 2);
131497
+ rows = rows.filter((r) => rowValueAfter(keysOf(r), cursor.values, desc));
131256
131498
  }
131257
- let top = -1;
131258
- for (const r of records) if (/^\d{1,15}$/.test(r.id)) top = Math.max(top, Number(r.id));
131259
- if (top >= 0) sequences.set(kind, Math.max(sequences.get(kind) ?? 0, top + 1));
131260
- afterWrite(kind, records.map((r) => r.deviceId));
131261
- return {
131262
- count: records.length,
131263
- releasedRefs: released
131264
- };
131265
- },
131266
- patch: async (input) => {
131267
- writing();
131268
- const decl = declOf(input.kind);
131269
- if (input.at !== void 0 && decl.at !== "required") throw new InvalidRecordError(`${input.kind}: declared at: "none"`);
131270
- if (input.at === null) throw new InvalidRecordError(`${input.kind}: "at" cannot be removed`);
131271
- if (input.expiresAt !== void 0 && decl.secretPaths.length > 0) throw new InvalidRecordError(`${input.kind}: a kind with secret fields cannot expire by the engine (its keychain values would be orphaned)`);
131272
- if (input.expiresAt !== void 0 && "ttlMs" in decl.retention) throw new InvalidRecordError(`${input.kind}: expiresAt is set by the engine`);
131273
- const before = table(input.kind).get(input.id);
131274
- const checked = enforceSecrets(owner, input.kind, decl, input.id, input.data, before?.data ?? null, "patch");
131275
- if (before === void 0) throw new RecordNotFoundError(`${input.kind}/${input.id}: no such row`);
131276
- if (input.ifRev !== void 0 && before.rev !== input.ifRev) throw new RevConflictError(`${input.kind}/${input.id}: expected rev ${String(input.ifRev)}, found rev ${before.rev}`);
131277
- const merged = jsonCopy(mergePatch(before.data, jsonCopy(checked.body)));
131278
- const size = [...JSON.stringify(merged)].length;
131279
- if (size > decl.maxDataBytes) throw new RecordTooLargeError(`${input.kind}/${input.id}: the patched body is ${size} bytes, over maxDataBytes ${decl.maxDataBytes}`);
131280
- assertUnique(input.kind, decl, input.id, merged);
131281
- const rev = before.rev + 1;
131282
- store2(input.kind, before, {
131283
- ...before,
131284
- at: input.at ?? before.at,
131285
- expiresAt: input.expiresAt === void 0 ? before.expiresAt : input.expiresAt,
131286
- rev,
131287
- updatedAt: now(),
131288
- data: merged
131499
+ } else {
131500
+ if (q.deviceId !== void 0 || q.atFrom !== void 0 || q.atTo !== void 0) throw new UnindexedFilterError(`${q.kind}: order "id" cannot be combined with a device or time window (use order "at")`);
131501
+ keysOf = (row) => [row.id, row.rid];
131502
+ tag = `id:${dir}`;
131503
+ if (cursor !== void 0) {
131504
+ assertCursor(cursor, tag, 2);
131505
+ const last2 = cursor.values[0] ?? null;
131506
+ rows = rows.filter((r) => rowValueAfter([r.id], [last2], desc));
131507
+ }
131508
+ }
131509
+ }
131510
+ rows.sort((a, b) => (desc ? -1 : 1) * compareKeys(keysOf(a), keysOf(b)));
131511
+ const page = rows.slice(0, q.limit);
131512
+ const more = rows.length > q.limit;
131513
+ const last = page.at(-1);
131514
+ let nextCursor = null;
131515
+ if (more && last !== void 0) {
131516
+ const all = keysOf(last);
131517
+ const keys = [];
131518
+ for (let i = 0; i < keyCount; i += 1) {
131519
+ const value = all[i];
131520
+ if (typeof value !== "string" && typeof value !== "number") throw new InvalidRecordError(`${q.kind}: a row has no value for an ordering field, so this query cannot be paged`);
131521
+ keys.push(value);
131522
+ }
131523
+ keys.push(last.rid);
131524
+ nextCursor = encodeCursor(tag, keys);
131525
+ }
131526
+ return {
131527
+ records: page.map((r) => view(decl, r)),
131528
+ nextCursor
131529
+ };
131530
+ },
131531
+ count: async (q) => {
131532
+ reading();
131533
+ const decl = declOf(q.kind);
131534
+ assertWindowAllowed(q.kind, decl, q);
131535
+ const where = planWhere(q.kind, decl, q.where, { allowIn: true });
131536
+ let n = 0;
131537
+ for (const row of table(q.kind).values()) if (inWindow(row, q) && (where === null || where.matches(row.data))) n += 1;
131538
+ return { count: n };
131539
+ },
131540
+ histogram: async (q) => {
131541
+ reading();
131542
+ const decl = declOf(q.kind);
131543
+ assertWindowAllowed(q.kind, decl, {
131544
+ deviceId: q.deviceId,
131545
+ atFrom: q.from
131546
+ });
131547
+ if (!(q.to > q.from)) throw new InvalidRecordError(`${q.kind}: histogram needs from < to`);
131548
+ if (Math.ceil((q.to - q.from) / q.bucketMs) > 1e4) throw new InvalidRecordError(`${q.kind}: histogram would exceed ${HISTOGRAM_MAX_BUCKETS} buckets`);
131549
+ const from = Math.floor(q.from);
131550
+ const to = Math.ceil(q.to);
131551
+ const step = Math.trunc(q.bucketMs);
131552
+ const counts = /* @__PURE__ */ new Map();
131553
+ for (const row of table(q.kind).values()) {
131554
+ if (q.deviceId !== void 0 && row.deviceId !== q.deviceId) continue;
131555
+ if (row.at === null || row.at < from || row.at >= to) continue;
131556
+ const b = Math.trunc((row.at - from) / step);
131557
+ counts.set(b, (counts.get(b) ?? 0) + 1);
131558
+ }
131559
+ return { buckets: [...counts.entries()].sort(([a], [b]) => a - b).map(([b, count]) => ({
131560
+ bucketStart: from + b * q.bucketMs,
131561
+ count
131562
+ })) };
131563
+ },
131564
+ aggregate: async (q) => {
131565
+ reading();
131566
+ const decl = declOf(q.kind);
131567
+ if (q.op !== "count" && q.field === void 0) throw new InvalidRecordError(`${q.kind}: ${q.op} needs a field`);
131568
+ const extra = [q.field, q.groupBy].filter((f) => f !== void 0);
131569
+ if (extra.length === 0 && q.where === void 0) throw new InvalidRecordError(`${q.kind}: a count with no field and no groupBy is "count"`);
131570
+ const where = planWhere(q.kind, decl, q.where, {
131571
+ allowIn: true,
131572
+ extraFields: extra,
131573
+ groupBy: q.groupBy
131574
+ });
131575
+ if (where === null) throw new InvalidRecordError(`${q.kind}: aggregate has nothing to read`);
131576
+ const rows = [...table(q.kind).values()].filter((r) => where.matches(r.data));
131577
+ const groups = /* @__PURE__ */ new Map();
131578
+ if (q.groupBy === void 0) groups.set(null, rows);
131579
+ else {
131580
+ const by = q.groupBy;
131581
+ for (const row of rows) {
131582
+ const g = extractField(row.data, by);
131583
+ groups.set(g, [...groups.get(g) ?? [], row]);
131584
+ }
131585
+ }
131586
+ return { rows: [...groups.entries()].sort(([a], [b]) => compareSql(a, b)).map(([group, members]) => ({
131587
+ group,
131588
+ value: aggregateOf(q.op, q.field, members)
131589
+ })) };
131590
+ },
131591
+ deleteWhere: async (q) => {
131592
+ writing();
131593
+ const decl = declOf(q.kind);
131594
+ if (q.deviceId === void 0 && q.atBefore === void 0 && (q.where === void 0 || Object.keys(q.where).length === 0)) throw new FilterRequiredError(`${q.kind}: deleteWhere needs deviceId, atBefore or where - there is no "delete all"`);
131595
+ assertWindowAllowed(q.kind, decl, {
131596
+ deviceId: q.deviceId,
131597
+ atFrom: q.atBefore
131598
+ });
131599
+ const where = planWhere(q.kind, decl, q.where, { allowIn: true });
131600
+ return removeWhere(q.kind, (row) => {
131601
+ if (where !== null && !where.matches(row.data)) return false;
131602
+ if (q.deviceId !== void 0 && row.deviceId !== q.deviceId) return false;
131603
+ if (q.atBefore !== void 0 && (row.at === null || row.at >= q.atBefore)) return false;
131604
+ return true;
131605
+ });
131606
+ },
131607
+ transact: async ({ ops }) => {
131608
+ writing();
131609
+ assertTransactScope(ops.map((op) => ({
131610
+ kind: op.kind,
131611
+ declaration: declOf(op.kind)
131612
+ })));
131613
+ const before = new Map([...tables].map(([name, rows]) => [name, new Map(rows)]));
131614
+ const ridBefore = nextRid;
131615
+ const results = [];
131616
+ const releasedRefs = [];
131617
+ const secretRefs = [];
131618
+ try {
131619
+ for (const op of ops) if (op.op === "put") {
131620
+ const r = await transport.put({
131621
+ kind: op.kind,
131622
+ record: op.record,
131623
+ ...op.ifRev === void 0 ? {} : { ifRev: op.ifRev }
131289
131624
  });
131290
- const kept = new Set(markersOf(decl, merged).values());
131291
- return {
131292
- rev,
131293
- releasedRefs: [...markersOf(decl, before.data).values()].filter((r) => !kept.has(r))
131294
- };
131295
- },
131296
- delete: async ({ kind, id }) => {
131297
- writing();
131298
- const decl = declOf(kind);
131299
- const row = table(kind).get(id);
131300
- if (row === void 0) return {
131301
- deleted: false,
131302
- secretRefs: []
131303
- };
131304
- table(kind).delete(id);
131305
- return {
131306
- deleted: true,
131307
- secretRefs: refsOf(decl, [row])
131308
- };
131309
- },
131310
- deleteMany: async ({ kind, ids }) => {
131311
- writing();
131312
- const wanted = new Set(ids);
131313
- return removeWhere(kind, (row) => wanted.has(row.id));
131314
- },
131315
- query: async (q) => {
131316
- reading();
131317
- const decl = declOf(q.kind);
131318
- queries.push({
131319
- kind: q.kind,
131320
- limit: q.limit
131625
+ releasedRefs.push(...r.releasedRefs);
131626
+ results.push({
131627
+ rev: r.rev,
131628
+ deleted: false
131321
131629
  });
131322
- assertWindowAllowed(q.kind, decl, q);
131323
- const desc = q.desc === true;
131324
- const dir = desc ? "DESC" : "ASC";
131325
- const where = planWhere(q.kind, decl, q.where, { allowIn: false });
131326
- const cursor = q.cursor === void 0 ? void 0 : decodeCursor(q.cursor);
131327
- let rows = [...table(q.kind).values()].filter((r) => inWindow(r, q));
131328
- let keysOf;
131329
- let keyCount;
131330
- let tag;
131331
- if (where !== null) {
131332
- if (q.order !== void 0) throw new InvalidRecordError(`${q.kind}: with a where the order is the index's; drop "order"`);
131333
- const fields = where.orderFields;
131334
- keysOf = (row) => [...fields.map((f) => extractField(row.data, f)), row.rid];
131335
- keyCount = fields.length;
131336
- tag = `rx:${where.indexName}:${dir}`;
131337
- rows = rows.filter((r) => where.matches(r.data));
131338
- if (cursor !== void 0) {
131339
- assertCursor(cursor, tag, fields.length + 1);
131340
- rows = rows.filter((r) => rowValueAfter(keysOf(r), cursor.values, desc));
131341
- }
131342
- } else {
131343
- const order = q.order ?? (decl.at === "required" ? "at" : "id");
131344
- keyCount = 1;
131345
- if (order === "at") {
131346
- if (decl.at !== "required") throw new InvalidRecordError(`${q.kind}: declared at: "none", it has no time order - use order: "id"`);
131347
- keysOf = (row) => [row.at, row.rid];
131348
- tag = `at:${dir}`;
131349
- if (cursor !== void 0) {
131350
- assertCursor(cursor, tag, 2);
131351
- rows = rows.filter((r) => rowValueAfter(keysOf(r), cursor.values, desc));
131352
- }
131353
- } else {
131354
- if (q.deviceId !== void 0 || q.atFrom !== void 0 || q.atTo !== void 0) throw new UnindexedFilterError(`${q.kind}: order "id" cannot be combined with a device or time window (use order "at")`);
131355
- keysOf = (row) => [row.id, row.rid];
131356
- tag = `id:${dir}`;
131357
- if (cursor !== void 0) {
131358
- assertCursor(cursor, tag, 2);
131359
- const last2 = cursor.values[0] ?? null;
131360
- rows = rows.filter((r) => rowValueAfter([r.id], [last2], desc));
131361
- }
131362
- }
131363
- }
131364
- rows.sort((a, b) => (desc ? -1 : 1) * compareKeys(keysOf(a), keysOf(b)));
131365
- const page = rows.slice(0, q.limit);
131366
- const more = rows.length > q.limit;
131367
- const last = page.at(-1);
131368
- let nextCursor = null;
131369
- if (more && last !== void 0) {
131370
- const all = keysOf(last);
131371
- const keys = [];
131372
- for (let i = 0; i < keyCount; i += 1) {
131373
- const value = all[i];
131374
- if (typeof value !== "string" && typeof value !== "number") throw new InvalidRecordError(`${q.kind}: a row has no value for an ordering field, so this query cannot be paged`);
131375
- keys.push(value);
131376
- }
131377
- keys.push(last.rid);
131378
- nextCursor = encodeCursor(tag, keys);
131379
- }
131380
- return {
131381
- records: page.map((r) => view(decl, r)),
131382
- nextCursor
131383
- };
131384
- },
131385
- count: async (q) => {
131386
- reading();
131387
- const decl = declOf(q.kind);
131388
- assertWindowAllowed(q.kind, decl, q);
131389
- const where = planWhere(q.kind, decl, q.where, { allowIn: true });
131390
- let n = 0;
131391
- for (const row of table(q.kind).values()) if (inWindow(row, q) && (where === null || where.matches(row.data))) n += 1;
131392
- return { count: n };
131393
- },
131394
- histogram: async (q) => {
131395
- reading();
131396
- const decl = declOf(q.kind);
131397
- assertWindowAllowed(q.kind, decl, {
131398
- deviceId: q.deviceId,
131399
- atFrom: q.from
131630
+ } else if (op.op === "patch") {
131631
+ const r = await transport.patch({
131632
+ kind: op.kind,
131633
+ id: op.id,
131634
+ data: op.data,
131635
+ ...op.at === void 0 ? {} : { at: op.at },
131636
+ ...op.expiresAt === void 0 ? {} : { expiresAt: op.expiresAt },
131637
+ ...op.ifRev === void 0 ? {} : { ifRev: op.ifRev }
131400
131638
  });
131401
- if (!(q.to > q.from)) throw new InvalidRecordError(`${q.kind}: histogram needs from < to`);
131402
- if (Math.ceil((q.to - q.from) / q.bucketMs) > 1e4) throw new InvalidRecordError(`${q.kind}: histogram would exceed ${HISTOGRAM_MAX_BUCKETS} buckets`);
131403
- const from = Math.floor(q.from);
131404
- const to = Math.ceil(q.to);
131405
- const step = Math.trunc(q.bucketMs);
131406
- const counts = /* @__PURE__ */ new Map();
131407
- for (const row of table(q.kind).values()) {
131408
- if (q.deviceId !== void 0 && row.deviceId !== q.deviceId) continue;
131409
- if (row.at === null || row.at < from || row.at >= to) continue;
131410
- const b = Math.trunc((row.at - from) / step);
131411
- counts.set(b, (counts.get(b) ?? 0) + 1);
131412
- }
131413
- return { buckets: [...counts.entries()].sort(([a], [b]) => a - b).map(([b, count]) => ({
131414
- bucketStart: from + b * q.bucketMs,
131415
- count
131416
- })) };
131417
- },
131418
- aggregate: async (q) => {
131419
- reading();
131420
- const decl = declOf(q.kind);
131421
- if (q.op !== "count" && q.field === void 0) throw new InvalidRecordError(`${q.kind}: ${q.op} needs a field`);
131422
- const extra = [q.field, q.groupBy].filter((f) => f !== void 0);
131423
- if (extra.length === 0 && q.where === void 0) throw new InvalidRecordError(`${q.kind}: a count with no field and no groupBy is "count"`);
131424
- const where = planWhere(q.kind, decl, q.where, {
131425
- allowIn: true,
131426
- extraFields: extra,
131427
- groupBy: q.groupBy
131639
+ releasedRefs.push(...r.releasedRefs);
131640
+ results.push({
131641
+ rev: r.rev,
131642
+ deleted: false
131428
131643
  });
131429
- if (where === null) throw new InvalidRecordError(`${q.kind}: aggregate has nothing to read`);
131430
- const rows = [...table(q.kind).values()].filter((r) => where.matches(r.data));
131431
- const groups = /* @__PURE__ */ new Map();
131432
- if (q.groupBy === void 0) groups.set(null, rows);
131433
- else {
131434
- const by = q.groupBy;
131435
- for (const row of rows) {
131436
- const g = extractField(row.data, by);
131437
- groups.set(g, [...groups.get(g) ?? [], row]);
131438
- }
131439
- }
131440
- return { rows: [...groups.entries()].sort(([a], [b]) => compareSql(a, b)).map(([group, members]) => ({
131441
- group,
131442
- value: aggregateOf(q.op, q.field, members)
131443
- })) };
131444
- },
131445
- deleteWhere: async (q) => {
131446
- writing();
131447
- const decl = declOf(q.kind);
131448
- if (q.deviceId === void 0 && q.atBefore === void 0 && (q.where === void 0 || Object.keys(q.where).length === 0)) throw new FilterRequiredError(`${q.kind}: deleteWhere needs deviceId, atBefore or where - there is no "delete all"`);
131449
- assertWindowAllowed(q.kind, decl, {
131450
- deviceId: q.deviceId,
131451
- atFrom: q.atBefore
131644
+ } else {
131645
+ const r = await transport.delete({
131646
+ kind: op.kind,
131647
+ id: op.id
131452
131648
  });
131453
- const where = planWhere(q.kind, decl, q.where, { allowIn: true });
131454
- return removeWhere(q.kind, (row) => {
131455
- if (where !== null && !where.matches(row.data)) return false;
131456
- if (q.deviceId !== void 0 && row.deviceId !== q.deviceId) return false;
131457
- if (q.atBefore !== void 0 && (row.at === null || row.at >= q.atBefore)) return false;
131458
- return true;
131649
+ secretRefs.push(...r.secretRefs);
131650
+ results.push({
131651
+ rev: null,
131652
+ deleted: r.deleted
131459
131653
  });
131460
- },
131461
- deleteDevice: async ({ deviceId, kinds }) => {
131462
- writing();
131463
- const deleted = {};
131464
- const secretRefs = [];
131465
- for (const [kind, decl] of decls) {
131466
- if (decl.deviceRemoval !== "delete") continue;
131467
- if (kinds !== void 0 && !kinds.includes(kind)) continue;
131468
- const result = removeWhere(kind, (row) => row.deviceId === deviceId);
131469
- deleted[kind] = result.deleted;
131470
- secretRefs.push(...result.secretRefs);
131471
- }
131472
- return {
131473
- deleted,
131474
- secretRefs
131475
- };
131476
- },
131477
- allocateId: async ({ kind }) => {
131478
- writing();
131479
- declOf(kind);
131480
- const id = sequences.get(kind) ?? 1;
131481
- sequences.set(kind, id + 1);
131482
- pendingAllocated.add(`${kind}:${id}`);
131483
- return { id };
131484
131654
  }
131485
- },
131655
+ } catch (err) {
131656
+ tables.clear();
131657
+ for (const [name, rows] of before) tables.set(name, rows);
131658
+ nextRid = ridBefore;
131659
+ throw err;
131660
+ }
131661
+ return {
131662
+ results,
131663
+ releasedRefs,
131664
+ secretRefs
131665
+ };
131666
+ },
131667
+ deleteDevice: async ({ deviceId, kinds }) => {
131668
+ writing();
131669
+ const deleted = {};
131670
+ const secretRefs = [];
131671
+ for (const [kind, decl] of decls) {
131672
+ if (decl.deviceRemoval !== "delete") continue;
131673
+ if (kinds !== void 0 && !kinds.includes(kind)) continue;
131674
+ const result = removeWhere(kind, (row) => row.deviceId === deviceId);
131675
+ deleted[kind] = result.deleted;
131676
+ secretRefs.push(...result.secretRefs);
131677
+ }
131678
+ return {
131679
+ deleted,
131680
+ secretRefs
131681
+ };
131682
+ },
131683
+ allocateId: async ({ kind }) => {
131684
+ writing();
131685
+ declOf(kind);
131686
+ const id = sequences.get(kind) ?? 1;
131687
+ sequences.set(kind, id + 1);
131688
+ pendingAllocated.add(`${kind}:${id}`);
131689
+ return { id };
131690
+ }
131691
+ };
131692
+ return {
131693
+ records: createRecordsAccess({
131694
+ owner,
131695
+ transport,
131486
131696
  secrets: makeSpecKeychain(owner).access
131487
131697
  }),
131488
131698
  tables,
@@ -134507,6 +134717,12 @@ var require_sleep_Bo7fq491 = __commonJS({
134507
134717
  return SHARE_VIEW_KINDS;
134508
134718
  }
134509
134719
  });
134720
+ Object.defineProperty(exports, "StoredRecordKindDeclarationSchema", {
134721
+ enumerable: true,
134722
+ get: function() {
134723
+ return StoredRecordKindDeclarationSchema;
134724
+ }
134725
+ });
134510
134726
  Object.defineProperty(exports, "StreamSourceEntrySchema", {
134511
134727
  enumerable: true,
134512
134728
  get: function() {
@@ -134531,6 +134747,12 @@ var require_sleep_Bo7fq491 = __commonJS({
134531
134747
  return SubscribeAudioChunksResultSchema;
134532
134748
  }
134533
134749
  });
134750
+ Object.defineProperty(exports, "TransactRefusedError", {
134751
+ enumerable: true,
134752
+ get: function() {
134753
+ return TransactRefusedError;
134754
+ }
134755
+ });
134534
134756
  Object.defineProperty(exports, "UnindexedFilterError", {
134535
134757
  enumerable: true,
134536
134758
  get: function() {
@@ -134609,6 +134831,12 @@ var require_sleep_Bo7fq491 = __commonJS({
134609
134831
  return asString;
134610
134832
  }
134611
134833
  });
134834
+ Object.defineProperty(exports, "assertTransactScope", {
134835
+ enumerable: true,
134836
+ get: function() {
134837
+ return assertTransactScope;
134838
+ }
134839
+ });
134612
134840
  Object.defineProperty(exports, "assertValidDeclaration", {
134613
134841
  enumerable: true,
134614
134842
  get: function() {
@@ -135265,8 +135493,8 @@ var require_addon = __commonJS({
135265
135493
  "../types/dist/addon.js"(exports) {
135266
135494
  "use strict";
135267
135495
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
135268
- var require_sleep = require_sleep_Bo7fq491();
135269
- var require_event_category = require_event_category_kpu1bZMs();
135496
+ var require_sleep = require_sleep_CD18m9HF();
135497
+ var require_event_category = require_event_category_7AwNbPjm();
135270
135498
  var require_err_msg = require_err_msg_BhVbr0NX();
135271
135499
  var CAP_INPUT_DEFAULTS = Object.freeze({
135272
135500
  "addons": { "getLogs": { "limit": 100 } },
@@ -136282,6 +136510,18 @@ var require_addon = __commonJS({
136282
136510
  "empty"
136283
136511
  ]
136284
136512
  },
136513
+ {
136514
+ "path": "filterCleaningDue",
136515
+ "valueType": "boolean"
136516
+ },
136517
+ {
136518
+ "path": "machineCareDue",
136519
+ "valueType": "boolean"
136520
+ },
136521
+ {
136522
+ "path": "machineCareRemainingRuns",
136523
+ "valueType": "number"
136524
+ },
136285
136525
  {
136286
136526
  "path": "halfLoad",
136287
136527
  "valueType": "boolean"
@@ -137543,6 +137783,8 @@ var require_addon = __commonJS({
137543
137783
  exports.RevConflictError = require_sleep.RevConflictError;
137544
137784
  exports.SECRET_CLEAR = require_sleep.SECRET_CLEAR;
137545
137785
  exports.SECRET_REF_SCHEME = require_sleep.SECRET_REF_SCHEME;
137786
+ exports.StoredRecordKindDeclarationSchema = require_sleep.StoredRecordKindDeclarationSchema;
137787
+ exports.TransactRefusedError = require_sleep.TransactRefusedError;
137546
137788
  exports.UnindexedFilterError = require_sleep.UnindexedFilterError;
137547
137789
  exports.UnknownRecordKindError = require_sleep.UnknownRecordKindError;
137548
137790
  exports.addonSliceHandleApi = require_sleep.addonSliceHandleApi;
@@ -137551,6 +137793,7 @@ var require_addon = __commonJS({
137551
137793
  exports.asJsonObject = require_sleep.asJsonObject;
137552
137794
  exports.asRecordsError = require_sleep.asRecordsError;
137553
137795
  exports.asString = require_sleep.asString;
137796
+ exports.assertTransactScope = require_sleep.assertTransactScope;
137554
137797
  exports.assertValidDeclaration = require_sleep.assertValidDeclaration;
137555
137798
  exports.buildSecretRef = require_sleep.buildSecretRef;
137556
137799
  exports.classifySecretWrite = require_sleep.classifySecretWrite;
@@ -137908,7 +138151,7 @@ var require_device_manager_addon = __commonJS({
137908
138151
  [Symbol.toStringTag]: { value: "Module" }
137909
138152
  });
137910
138153
  require_chunk_Cek0wNdY();
137911
- var require_dist10 = require_dist_Dwi4JA96();
138154
+ var require_dist10 = require_dist_QyW9hVO2();
137912
138155
  var require_read_all_rows$1 = require_read_all_rows_CVoO1ONM();
137913
138156
  var require_prefix_range = require_prefix_range_D_KueXbQ();
137914
138157
  var require_prefix_walk = require_prefix_walk_Dv6MLZlM();
@@ -146980,7 +147223,7 @@ var require_hub_forwarder = __commonJS({
146980
147223
  [Symbol.toStringTag]: { value: "Module" }
146981
147224
  });
146982
147225
  require_chunk_Cek0wNdY();
146983
- var require_dist10 = require_dist_Dwi4JA96();
147226
+ var require_dist10 = require_dist_QyW9hVO2();
146984
147227
  var require_formatter = require_formatter_DqAKDlvN();
146985
147228
  var DEFAULT_OUTBOUND_BUFFER_SIZE = 500;
146986
147229
  var HubForwarderDestination = class {
@@ -147114,7 +147357,7 @@ var require_liveness_monitor_addon = __commonJS({
147114
147357
  "use strict";
147115
147358
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
147116
147359
  require_chunk_Cek0wNdY();
147117
- var require_dist10 = require_dist_Dwi4JA96();
147360
+ var require_dist10 = require_dist_QyW9hVO2();
147118
147361
  var NO_DEVICES = "liveness:no-devices";
147119
147362
  var ALL_OFFLINE = "liveness:all-devices-offline";
147120
147363
  var NO_FOOTAGE_PREFIX = "liveness:no-footage:";
@@ -147477,11 +147720,11 @@ var require_local_auth_addon = __commonJS({
147477
147720
  [Symbol.toStringTag]: { value: "Module" }
147478
147721
  });
147479
147722
  var require_chunk = require_chunk_Cek0wNdY();
147480
- var require_dist10 = require_dist_Dwi4JA96();
147481
- var require_read_all_rows$1 = require_read_all_rows_CVoO1ONM();
147723
+ var require_dist10 = require_dist_QyW9hVO2();
147482
147724
  var require_safe_buffer$1 = require_safe_buffer_D3aoa_7X();
147483
147725
  var require_ms$1 = require_ms_LB3giGoU();
147484
- var require_device_ca = require_device_ca_B_Txwl4W();
147726
+ var require_device_ca = require_device_ca_DpvQ5wrb();
147727
+ var require_read_all_rows$1 = require_read_all_rows_CVoO1ONM();
147485
147728
  var zod = require_zod();
147486
147729
  var node_crypto = __require("crypto");
147487
147730
  node_crypto = require_chunk.__toESM(node_crypto);
@@ -147491,75 +147734,6 @@ var require_local_auth_addon = __commonJS({
147491
147734
  node_path = require_chunk.__toESM(node_path);
147492
147735
  var node_fs = __require("fs");
147493
147736
  node_fs = require_chunk.__toESM(node_fs);
147494
- function parseRecord$2(kind, schema, data) {
147495
- try {
147496
- return schema.parse(data);
147497
- } catch (err) {
147498
- const topKeys = data && typeof data === "object" && !Array.isArray(data) ? Object.keys(data).join(", ") || "(empty)" : `(non-object: ${typeof data})`;
147499
- const detail = err instanceof Error ? err.message : String(err);
147500
- const hint = data && typeof data === "object" && !Array.isArray(data) && Object.keys(data).length === 1 && "data" in data ? " This shape is the legacy double-wrap from a stale settings-store query path. Restart the server with the latest @camstack/system build." : "";
147501
- throw new Error(`Failed to parse ${kind} from settings store. Top-level keys=[${topKeys}].${hint} Underlying: ${detail}`, { cause: err });
147502
- }
147503
- }
147504
- var import_read_all_rows = require_read_all_rows$1.require_read_all_rows();
147505
- var API_KEYS_COLLECTION$1 = "api_keys";
147506
- function parseApiKey(data) {
147507
- return parseRecord$2("api-key", require_dist10.ApiKeyRecordSchema, data);
147508
- }
147509
- function rowToApiKey(id, body) {
147510
- return parseApiKey({
147511
- id,
147512
- ...body
147513
- });
147514
- }
147515
- var ApiKeyManager = class {
147516
- kind;
147517
- legacyStore;
147518
- constructor(deps) {
147519
- if ("apiKeysKind" in deps) {
147520
- this.kind = deps.apiKeysKind;
147521
- this.legacyStore = deps.legacyStore ?? null;
147522
- } else {
147523
- this.kind = null;
147524
- this.legacyStore = deps.getStore();
147525
- }
147526
- }
147527
- get store() {
147528
- if (this.legacyStore === null) throw new Error("ApiKeyManager: legacy store unavailable on records-only path");
147529
- return this.legacyStore;
147530
- }
147531
- async listAll() {
147532
- const kind = this.kind;
147533
- return (kind !== null ? (await (0, import_read_all_rows.readAllRows)(kind)).map((row) => rowToApiKey(row.id, row.data)) : (await this.store.query.query({ collection: API_KEYS_COLLECTION$1 })).map((r2) => parseApiKey(r2.data))).map((parsed) => {
147534
- const { tokenHash: _th, ...rest } = parsed;
147535
- return rest;
147536
- });
147537
- }
147538
- async revoke(id) {
147539
- const kind = this.kind;
147540
- if (kind !== null) {
147541
- await kind.delete(id);
147542
- return;
147543
- }
147544
- await this.store.delete.mutate({
147545
- collection: API_KEYS_COLLECTION$1,
147546
- key: id
147547
- });
147548
- }
147549
- async findById(id) {
147550
- const kind = this.kind;
147551
- if (kind !== null) {
147552
- const row = await kind.get(id);
147553
- return row === null ? null : rowToApiKey(row.id, row.data);
147554
- }
147555
- const results = await this.store.query.query({
147556
- collection: API_KEYS_COLLECTION$1,
147557
- filter: { where: { id } }
147558
- });
147559
- if (results.length === 0) return null;
147560
- return parseApiKey(results[0].data);
147561
- }
147562
- };
147563
147737
  var randomFallback = null;
147564
147738
  function randomBytes$1(len) {
147565
147739
  try {
@@ -152264,6 +152438,7 @@ var require_local_auth_addon = __commonJS({
152264
152438
  }
152265
152439
  }
152266
152440
  };
152441
+ var import_read_all_rows = require_read_all_rows$1.require_read_all_rows();
152267
152442
  var AUTH_AUDIT_COLLECTION = "auth_audit";
152268
152443
  var AUTH_AUDIT_COLUMNS = [
152269
152444
  {
@@ -152312,7 +152487,7 @@ var require_local_auth_addon = __commonJS({
152312
152487
  ];
152313
152488
  var RETENTION_MS = 90 * 864e5;
152314
152489
  var MAX_LIST = 500;
152315
- function parseRecord$1(data) {
152490
+ function parseRecord$2(data) {
152316
152491
  const id = data["id"];
152317
152492
  const rawAt = data["at"];
152318
152493
  const at = typeof rawAt === "number" ? rawAt : typeof rawAt === "string" && rawAt.trim() !== "" && Number.isFinite(Number(rawAt)) ? Number(rawAt) : null;
@@ -152405,7 +152580,7 @@ var require_local_auth_addon = __commonJS({
152405
152580
  order: "at",
152406
152581
  desc: true,
152407
152582
  limit
152408
- })).records.map((row) => parseRecord$1({
152583
+ })).records.map((row) => parseRecord$2({
152409
152584
  id: row.id,
152410
152585
  at: row.at,
152411
152586
  action: row.data.action,
@@ -152416,7 +152591,7 @@ var require_local_auth_addon = __commonJS({
152416
152591
  return (await this.store.query.query({
152417
152592
  collection: AUTH_AUDIT_COLLECTION,
152418
152593
  ...input.userId !== void 0 ? { filter: { where: { userId: input.userId } } } : {}
152419
- })).map((row) => parseRecord$1(row.data)).filter((r2) => r2 !== null).toSorted((a2, b) => b.at - a2.at).slice(0, limit);
152594
+ })).map((row) => parseRecord$2(row.data)).filter((r2) => r2 !== null).toSorted((a2, b) => b.at - a2.at).slice(0, limit);
152420
152595
  }
152421
152596
  /** Delete rows older than 90 days. Returns how many. */
152422
152597
  async reap() {
@@ -152590,7 +152765,7 @@ var require_local_auth_addon = __commonJS({
152590
152765
  "web",
152591
152766
  "other"
152592
152767
  ];
152593
- function parseRecord(data) {
152768
+ function parseRecord$1(data) {
152594
152769
  const id = str$1(data, "id");
152595
152770
  const userId = str$1(data, "userId");
152596
152771
  const deviceName = str$1(data, "deviceName");
@@ -152655,7 +152830,7 @@ var require_local_auth_addon = __commonJS({
152655
152830
  const kind = this.deps.deviceCredentialsKind ?? null;
152656
152831
  if (kind !== null) {
152657
152832
  for (const row of await (0, import_read_all_rows.readAllRows)(kind)) {
152658
- const record = parseRecord({
152833
+ const record = parseRecord$1({
152659
152834
  id: row.id,
152660
152835
  ...row.data
152661
152836
  });
@@ -152665,7 +152840,7 @@ var require_local_auth_addon = __commonJS({
152665
152840
  }
152666
152841
  const rows = await this.store.query.query({ collection: DEVICE_CREDENTIALS_COLLECTION });
152667
152842
  for (const row of rows) {
152668
- const record = parseRecord(row.data);
152843
+ const record = parseRecord$1(row.data);
152669
152844
  if (record !== null) this.records.set(record.id, record);
152670
152845
  }
152671
152846
  }
@@ -153066,7 +153241,6 @@ var require_local_auth_addon = __commonJS({
153066
153241
  }
153067
153242
  };
153068
153243
  var USERS_COLLECTION$1 = "users";
153069
- var API_KEYS_COLLECTION = "api_keys";
153070
153244
  var SCOPED_TOKENS_COLLECTION = "scoped_tokens";
153071
153245
  var USER_TOTP_COLLECTION = "user_totp";
153072
153246
  var USER_EXTERNAL_IDENTITIES_COLLECTION = "user_external_identities";
@@ -153116,52 +153290,6 @@ var require_local_auth_addon = __commonJS({
153116
153290
  notNull: true
153117
153291
  }
153118
153292
  ];
153119
- var API_KEYS_COLUMNS = [
153120
- {
153121
- name: "id",
153122
- type: "TEXT",
153123
- primaryKey: true,
153124
- notNull: true
153125
- },
153126
- {
153127
- name: "label",
153128
- type: "TEXT",
153129
- notNull: true
153130
- },
153131
- {
153132
- name: "isAdmin",
153133
- type: "BOOLEAN",
153134
- notNull: true
153135
- },
153136
- {
153137
- name: "tokenHash",
153138
- type: "TEXT",
153139
- notNull: true,
153140
- unique: true
153141
- },
153142
- {
153143
- name: "tokenPrefix",
153144
- type: "TEXT",
153145
- notNull: true
153146
- },
153147
- {
153148
- name: "allowedProviders",
153149
- type: "JSON"
153150
- },
153151
- {
153152
- name: "allowedDevices",
153153
- type: "JSON"
153154
- },
153155
- {
153156
- name: "createdAt",
153157
- type: "INTEGER",
153158
- notNull: true
153159
- },
153160
- {
153161
- name: "lastUsedAt",
153162
- type: "INTEGER"
153163
- }
153164
- ];
153165
153293
  var USER_TOTP_COLUMNS = [
153166
153294
  {
153167
153295
  name: "userId",
@@ -153273,14 +153401,6 @@ var require_local_auth_addon = __commonJS({
153273
153401
  collection: USERS_COLLECTION$1,
153274
153402
  columns: USERS_COLUMNS
153275
153403
  });
153276
- if (!skip.has("api_keys")) await store.declareCollection.mutate({
153277
- collection: API_KEYS_COLLECTION,
153278
- columns: API_KEYS_COLUMNS,
153279
- indexes: [{
153280
- name: "idx_api_keys_token_prefix",
153281
- columns: ["tokenPrefix"]
153282
- }]
153283
- });
153284
153404
  if (!skip.has("scoped_tokens")) await store.declareCollection.mutate({
153285
153405
  collection: SCOPED_TOKENS_COLLECTION,
153286
153406
  columns: SCOPED_TOKENS_COLUMNS,
@@ -153340,7 +153460,6 @@ var require_local_auth_addon = __commonJS({
153340
153460
  }
153341
153461
  var DAY_MS = 864e5;
153342
153462
  var UserBodySchema = require_dist10.UserRecordSchema.omit({ id: true });
153343
- var ApiKeyBodySchema = require_dist10.ApiKeyRecordSchema.omit({ id: true });
153344
153463
  var ScopedTokenBodySchema = require_dist10.ScopedTokenSchema.omit({ id: true });
153345
153464
  var AdminTokenBodySchema = zod.z.object({
153346
153465
  createdBy: zod.z.string(),
@@ -153428,18 +153547,6 @@ var require_local_auth_addon = __commonJS({
153428
153547
  }],
153429
153548
  retention: { none: "row goes only when an operator deletes the user; destructive declareCollection rebuild wipes all accounts" }
153430
153549
  },
153431
- "api-keys": {
153432
- schema: ApiKeyBodySchema,
153433
- class: "config",
153434
- writeTrigger: "legacy list/revoke only \u2014 nothing creates new API keys",
153435
- device: "none",
153436
- at: "none",
153437
- indexes: [{
153438
- name: "prefix",
153439
- fields: ["tokenPrefix"]
153440
- }],
153441
- retention: { none: "explicit revoke only" }
153442
- },
153443
153550
  "scoped-tokens": {
153444
153551
  schema: ScopedTokenBodySchema,
153445
153552
  class: "config",
@@ -153576,7 +153683,6 @@ var require_local_auth_addon = __commonJS({
153576
153683
  });
153577
153684
  var localAuthRecordKinds = _localAuthRecordKinds;
153578
153685
  var localAuthUsersRecordKind = _localAuthRecordKinds.users;
153579
- var localAuthApiKeysRecordKind = _localAuthRecordKinds["api-keys"];
153580
153686
  _localAuthRecordKinds["scoped-tokens"];
153581
153687
  _localAuthRecordKinds["admin-tokens"];
153582
153688
  var localAuthLoginSessionsRecordKind = _localAuthRecordKinds["login-sessions"];
@@ -153588,7 +153694,6 @@ var require_local_auth_addon = __commonJS({
153588
153694
  var localAuthAuthAuditRecordKind = _localAuthRecordKinds["auth-audit"];
153589
153695
  var LOCAL_AUTH_RECORDS_LEGACY_COLLECTIONS = [
153590
153696
  USERS_COLLECTION$1,
153591
- API_KEYS_COLLECTION,
153592
153697
  SCOPED_TOKENS_COLLECTION,
153593
153698
  ADMIN_TOKENS_COLLECTION,
153594
153699
  LOGIN_SESSIONS_COLLECTION,
@@ -153601,7 +153706,6 @@ var require_local_auth_addon = __commonJS({
153601
153706
  function localAuthRecordStoresOf(records) {
153602
153707
  return {
153603
153708
  users: records.kind(localAuthUsersRecordKind),
153604
- apiKeys: records.kind(localAuthApiKeysRecordKind),
153605
153709
  loginSessions: records.kind(localAuthLoginSessionsRecordKind),
153606
153710
  loginSessionCutoffs: records.kind(localAuthLoginSessionCutoffsRecordKind),
153607
153711
  oauthSessions: records.kind(localAuthOauthSessionsRecordKind),
@@ -154433,11 +154537,21 @@ var require_local_auth_addon = __commonJS({
154433
154537
  if (internal === null || typeof internal !== "object") return null;
154434
154538
  return internal;
154435
154539
  }
154540
+ function parseRecord(kind, schema, data) {
154541
+ try {
154542
+ return schema.parse(data);
154543
+ } catch (err) {
154544
+ const topKeys = data && typeof data === "object" && !Array.isArray(data) ? Object.keys(data).join(", ") || "(empty)" : `(non-object: ${typeof data})`;
154545
+ const detail = err instanceof Error ? err.message : String(err);
154546
+ const hint = data && typeof data === "object" && !Array.isArray(data) && Object.keys(data).length === 1 && "data" in data ? " This shape is the legacy double-wrap from a stale settings-store query path. Restart the server with the latest @camstack/system build." : "";
154547
+ throw new Error(`Failed to parse ${kind} from settings store. Top-level keys=[${topKeys}].${hint} Underlying: ${detail}`, { cause: err });
154548
+ }
154549
+ }
154436
154550
  var USERS_COLLECTION = "users";
154437
154551
  var FIRST_BOOT_ADMIN_USERNAME = "admin";
154438
154552
  var FIRST_BOOT_ADMIN_PASSWORD = "changeme";
154439
154553
  function parseUser(data) {
154440
- return parseRecord$2("user", require_dist10.UserRecordSchema, data);
154554
+ return parseRecord("user", require_dist10.UserRecordSchema, data);
154441
154555
  }
154442
154556
  function userToBody(user) {
154443
154557
  const { id: _id, ...body } = user;
@@ -157253,7 +157367,6 @@ var require_local_auth_addon = __commonJS({
157253
157367
  var LocalAuthAddon = class extends require_dist10.BaseAddon {
157254
157368
  authManager = null;
157255
157369
  userManager = null;
157256
- apiKeyManager = null;
157257
157370
  oauthSessionManager = null;
157258
157371
  reapTimer = null;
157259
157372
  totpManager = null;
@@ -157289,10 +157402,6 @@ var require_local_auth_addon = __commonJS({
157289
157402
  usersKind: authStores.users,
157290
157403
  legacyStore: store
157291
157404
  }, this.authManager);
157292
- this.apiKeyManager = new ApiKeyManager({
157293
- apiKeysKind: authStores.apiKeys,
157294
- legacyStore: store
157295
- });
157296
157405
  this.oauthSessionManager = new OauthSessionManager({ oauthSessionsKind: authStores.oauthSessions });
157297
157406
  this.totpManager = new TotpManager({
157298
157407
  userTotpKind: authStores.userTotp,
@@ -157457,15 +157566,6 @@ var require_local_auth_addon = __commonJS({
157457
157566
  totpEnabled
157458
157567
  };
157459
157568
  },
157460
- listApiKeys: async () => {
157461
- if (!this.apiKeyManager) return [];
157462
- return this.apiKeyManager.listAll();
157463
- },
157464
- revokeApiKey: async (input) => {
157465
- if (!this.apiKeyManager) throw new Error("API key management not available");
157466
- await this.apiKeyManager.revoke(input.id);
157467
- return { success: true };
157468
- },
157469
157569
  oauthIssueCode: async (input) => {
157470
157570
  return lazyOauthGrants().oauthIssueCode(input);
157471
157571
  },
@@ -157826,7 +157926,6 @@ var require_local_auth_addon = __commonJS({
157826
157926
  }
157827
157927
  this.authManager = null;
157828
157928
  this.userManager = null;
157829
- this.apiKeyManager = null;
157830
157929
  this.oauthSessionManager = null;
157831
157930
  this.externalIdentities = null;
157832
157931
  this.loginSessions = null;
@@ -157835,7 +157934,6 @@ var require_local_auth_addon = __commonJS({
157835
157934
  this.deviceCa = null;
157836
157935
  }
157837
157936
  };
157838
- exports.ApiKeyManager = ApiKeyManager;
157839
157937
  exports.AuthAuditLog = AuthAuditLog;
157840
157938
  exports.AuthManager = AuthManager;
157841
157939
  exports.DeviceCaStore = DeviceCaStore;
@@ -158013,7 +158111,7 @@ var require_loki_logging = __commonJS({
158013
158111
  [Symbol.toStringTag]: { value: "Module" }
158014
158112
  });
158015
158113
  require_chunk_Cek0wNdY();
158016
- var require_dist10 = require_dist_Dwi4JA96();
158114
+ var require_dist10 = require_dist_QyW9hVO2();
158017
158115
  var require_log_read_filter = require_log_read_filter_Bi066jwU();
158018
158116
  var zod = require_zod();
158019
158117
  function sanitizeLabelName(raw) {
@@ -158974,7 +159072,7 @@ var require_native_metrics_addon = __commonJS({
158974
159072
  [Symbol.toStringTag]: { value: "Module" }
158975
159073
  });
158976
159074
  var require_chunk = require_chunk_Cek0wNdY();
158977
- var require_dist10 = require_dist_Dwi4JA96();
159075
+ var require_dist10 = require_dist_QyW9hVO2();
158978
159076
  var node_fs_promises = __require("fs/promises");
158979
159077
  var node_util = __require("util");
158980
159078
  var node_os = __require("os");
@@ -161541,7 +161639,7 @@ var require_device_history_addon = __commonJS({
161541
161639
  [Symbol.toStringTag]: { value: "Module" }
161542
161640
  });
161543
161641
  require_chunk_Cek0wNdY();
161544
- var require_dist10 = require_dist_Dwi4JA96();
161642
+ var require_dist10 = require_dist_QyW9hVO2();
161545
161643
  var FIVE_MINUTES_MS = 5 * 6e4;
161546
161644
  var HOUR_MS = 60 * 6e4;
161547
161645
  var DAY_MS = 24 * HOUR_MS;
@@ -164587,7 +164685,7 @@ var require_filesystem_storage_addon = __commonJS({
164587
164685
  [Symbol.toStringTag]: { value: "Module" }
164588
164686
  });
164589
164687
  var require_chunk = require_chunk_Cek0wNdY();
164590
- var require_dist10 = require_dist_Dwi4JA96();
164688
+ var require_dist10 = require_dist_QyW9hVO2();
164591
164689
  var node_crypto = __require("crypto");
164592
164690
  var node_fs_promises = __require("fs/promises");
164593
164691
  var node_path = __require("path");
@@ -165697,12 +165795,12 @@ var require_lib = __commonJS({
165697
165795
  }
165698
165796
  });
165699
165797
 
165700
- // ../system/dist/wal-maintenance-BQlvAduo.js
165701
- var require_wal_maintenance_BQlvAduo = __commonJS({
165702
- "../system/dist/wal-maintenance-BQlvAduo.js"(exports) {
165798
+ // ../system/dist/wal-maintenance-BIpPCYDi.js
165799
+ var require_wal_maintenance_BIpPCYDi = __commonJS({
165800
+ "../system/dist/wal-maintenance-BIpPCYDi.js"(exports) {
165703
165801
  "use strict";
165704
165802
  var require_chunk = require_chunk_Cek0wNdY();
165705
- var require_dist10 = require_dist_Dwi4JA96();
165803
+ var require_dist10 = require_dist_QyW9hVO2();
165706
165804
  var require_prefix_range = require_prefix_range_D_KueXbQ();
165707
165805
  var node_crypto = __require("crypto");
165708
165806
  var node_module = __require("module");
@@ -166162,7 +166260,7 @@ CREATE TABLE IF NOT EXISTS _record_sequences (
166162
166260
  database: asDatabase(row.database),
166163
166261
  hash: row.manifest_hash,
166164
166262
  state: asState(row.state),
166165
- declaration: require_dist10.RecordKindDeclarationSchema.parse(JSON.parse(row.declaration))
166263
+ declaration: require_dist10.StoredRecordKindDeclarationSchema.parse(JSON.parse(row.declaration))
166166
166264
  };
166167
166265
  }
166168
166266
  function ensureRecordsSchema(db) {
@@ -166202,8 +166300,10 @@ CREATE TABLE IF NOT EXISTS _record_sequences (
166202
166300
  state = "created";
166203
166301
  } else {
166204
166302
  kindId = prior.kindId;
166205
- if (prior.hash === hash) state = "unchanged";
166206
- else {
166303
+ if (prior.hash === hash) {
166304
+ db.prepare("UPDATE _record_kinds SET declaration = ? WHERE kind_id = ? AND declaration <> ?").run(JSON.stringify(declaration), kindId, JSON.stringify(declaration));
166305
+ state = "unchanged";
166306
+ } else {
166207
166307
  db.prepare("UPDATE _record_kinds SET manifest_hash = ?, declaration = ?, state = 'declared', orphaned_at = NULL WHERE kind_id = ?").run(hash, JSON.stringify(declaration), kindId);
166208
166308
  state = "updated";
166209
166309
  }
@@ -166230,8 +166330,7 @@ CREATE TABLE IF NOT EXISTS _record_sequences (
166230
166330
  result: {
166231
166331
  kindId,
166232
166332
  state,
166233
- createdIndexes: created,
166234
- adoptionPending: null
166333
+ createdIndexes: created
166235
166334
  }
166236
166335
  };
166237
166336
  })();
@@ -166861,13 +166960,17 @@ CREATE TABLE IF NOT EXISTS _record_sequences (
166861
166960
  }
166862
166961
  async patch(input) {
166863
166962
  const k = this.kindOf(input.owner, input.kind);
166864
- const decl = k.declaration;
166865
166963
  const nowMs = this.now();
166964
+ return this.timed("patch", input.kind, () => this.db.transaction(() => this.patchRecord(k, input, nowMs))());
166965
+ }
166966
+ /** One patch, inside the caller's transaction (shared with `transact`). */
166967
+ patchRecord(k, input, nowMs) {
166968
+ const decl = k.declaration;
166866
166969
  if (input.at !== void 0 && decl.at !== "required") throw new require_dist10.InvalidRecordError(`${input.kind}: declared at: "none"`);
166867
166970
  if (input.at === null) throw new require_dist10.InvalidRecordError(`${input.kind}: "at" cannot be removed`);
166868
166971
  if (input.expiresAt !== void 0 && decl.secretPaths.length > 0) throw new require_dist10.InvalidRecordError(`${input.kind}: a kind with secret fields cannot expire by the engine (its keychain values would be orphaned)`);
166869
166972
  if (input.expiresAt !== void 0 && "ttlMs" in decl.retention) throw new require_dist10.InvalidRecordError(`${input.kind}: expiresAt is set by the engine`);
166870
- const run = this.db.transaction(() => {
166973
+ {
166871
166974
  const hasSecrets = decl.secretPaths.length > 0;
166872
166975
  const before = hasSecrets || input.ifRev !== void 0 ? this.storedRow(k, input.id) : void 0;
166873
166976
  const checked = enforceSecrets(input.owner, input.kind, decl, input.id, input.data, before === void 0 ? null : parseBody(before.data), "patch");
@@ -166904,22 +167007,83 @@ CREATE TABLE IF NOT EXISTS _record_sequences (
166904
167007
  rev: updated.rev,
166905
167008
  releasedRefs: released
166906
167009
  };
166907
- });
166908
- return this.timed("patch", input.kind, () => run());
167010
+ }
166909
167011
  }
166910
167012
  refsOfRows(k, rows) {
166911
167013
  if (k.declaration.secretPaths.length === 0) return [];
166912
167014
  return rows.flatMap((row) => [...markersOf(k.declaration, parseBody(row.data)).values()]);
166913
167015
  }
166914
167016
  async delete(input) {
166915
- const k = this.kindOf(input.owner, input.kind);
167017
+ return this.deleteRecord(this.kindOf(input.owner, input.kind), input.id);
167018
+ }
167019
+ /** One delete (shared with `transact`). */
167020
+ deleteRecord(k, id) {
166916
167021
  const hasSecrets = k.declaration.secretPaths.length > 0;
166917
- const rows = this.db.prepare(`DELETE FROM records WHERE ${kindClause(k.kindId)} AND id = ? RETURNING ${hasSecrets ? "json(data)" : "'{}'"} AS data`).all(input.id);
167022
+ const rows = this.db.prepare(`DELETE FROM records WHERE ${kindClause(k.kindId)} AND id = ? RETURNING ${hasSecrets ? "json(data)" : "'{}'"} AS data`).all(id);
166918
167023
  return {
166919
167024
  deleted: rows.length > 0,
166920
167025
  secretRefs: this.refsOfRows(k, rows)
166921
167026
  };
166922
167027
  }
167028
+ /**
167029
+ * Several put / patch / delete in ONE SQLite transaction. The scope rule
167030
+ * (one file, one `transactFamily`) is checked before a row moves; each op then
167031
+ * runs the very code of the single-row write, so secrets, indexes and size
167032
+ * bounds behave exactly as there. Any op throwing rolls the whole call back.
167033
+ */
167034
+ async transact(input) {
167035
+ const kinds = /* @__PURE__ */ new Map();
167036
+ for (const op of input.ops) if (!kinds.has(op.kind)) kinds.set(op.kind, this.kindOf(input.owner, op.kind));
167037
+ require_dist10.assertTransactScope([...kinds.values()].map((k) => ({
167038
+ kind: k.kind,
167039
+ declaration: k.declaration
167040
+ })));
167041
+ const nowMs = this.now();
167042
+ const results = [];
167043
+ const releasedRefs = [];
167044
+ const secretRefs = [];
167045
+ const label = [...kinds.keys()].join("+");
167046
+ this.timed("transact", label, () => this.db.transaction(() => {
167047
+ for (const op of input.ops) {
167048
+ const k = kinds.get(op.kind);
167049
+ if (k === void 0) throw new require_dist10.UnknownRecordKindError(`"${input.owner}" declared no kind "${op.kind}"`);
167050
+ if (op.op === "put") {
167051
+ const w = this.writeRecord(input.owner, k, op.record, op.ifRev, nowMs);
167052
+ releasedRefs.push(...w.releasedRefs);
167053
+ results.push({
167054
+ rev: w.rev,
167055
+ deleted: false
167056
+ });
167057
+ } else if (op.op === "patch") {
167058
+ const w = this.patchRecord(k, {
167059
+ ...op,
167060
+ owner: input.owner
167061
+ }, nowMs);
167062
+ releasedRefs.push(...w.releasedRefs);
167063
+ results.push({
167064
+ rev: w.rev,
167065
+ deleted: false
167066
+ });
167067
+ } else {
167068
+ const d = this.deleteRecord(k, op.id);
167069
+ secretRefs.push(...d.secretRefs);
167070
+ results.push({
167071
+ rev: null,
167072
+ deleted: d.deleted
167073
+ });
167074
+ }
167075
+ }
167076
+ })());
167077
+ for (const [name, k] of kinds) {
167078
+ const devices = input.ops.flatMap((op) => op.op === "put" && op.kind === name ? [op.record.deviceId] : []);
167079
+ if (devices.length > 0) this.afterWrite(k, devices);
167080
+ }
167081
+ return {
167082
+ results,
167083
+ releasedRefs,
167084
+ secretRefs
167085
+ };
167086
+ }
166923
167087
  async deleteMany(input) {
166924
167088
  const k = this.kindOf(input.owner, input.kind);
166925
167089
  const hasSecrets = k.declaration.secretPaths.length > 0;
@@ -167074,6 +167238,7 @@ CREATE TABLE IF NOT EXISTS _record_sequences (
167074
167238
  "histogram",
167075
167239
  "aggregate",
167076
167240
  "deleteWhere",
167241
+ "transact",
167077
167242
  "deleteDevice",
167078
167243
  "allocateId",
167079
167244
  "listKinds",
@@ -169819,9 +169984,9 @@ var require_sqlite_settings_addon = __commonJS({
169819
169984
  [Symbol.toStringTag]: { value: "Module" }
169820
169985
  });
169821
169986
  var require_chunk = require_chunk_Cek0wNdY();
169822
- var require_dist10 = require_dist_Dwi4JA96();
169987
+ var require_dist10 = require_dist_QyW9hVO2();
169823
169988
  var require_retired_settings_keys = require_retired_settings_keys_CGUqX_Oz();
169824
- var require_wal_maintenance = require_wal_maintenance_BQlvAduo();
169989
+ var require_wal_maintenance = require_wal_maintenance_BIpPCYDi();
169825
169990
  var require_sqlite_snapshot_protocol = require_sqlite_snapshot_protocol_B9OndqZv();
169826
169991
  var require_wal_checkpoint_policy = require_wal_checkpoint_policy_d2z2qPqx();
169827
169992
  var node_fs_promises = __require("fs/promises");
@@ -170994,12 +171159,6 @@ var require_sqlite_settings_addon = __commonJS({
170994
171159
  function keyOf(owner, kind) {
170995
171160
  return `${owner}\0${kind}`;
170996
171161
  }
170997
- function withoutRetiredKeys(declaration) {
170998
- return {
170999
- ...declaration,
171000
- adoptsFrom: void 0
171001
- };
171002
- }
171003
171162
  var RecordsProvider = class {
171004
171163
  router;
171005
171164
  logger;
@@ -171033,7 +171192,7 @@ var require_sqlite_settings_addon = __commonJS({
171033
171192
  const owner = recordsCallerOf(input);
171034
171193
  const byDatabase = /* @__PURE__ */ new Map();
171035
171194
  const parsed = /* @__PURE__ */ new Map();
171036
- for (const [kind, raw] of Object.entries(input.kinds)) parsed.set(kind, withoutRetiredKeys(require_dist10.RecordKindDeclarationSchema.parse(raw)));
171195
+ for (const [kind, raw] of Object.entries(input.kinds)) parsed.set(kind, require_dist10.RecordKindDeclarationSchema.parse(raw));
171037
171196
  await this.assertFamiliesInOneFile(owner, parsed);
171038
171197
  for (const [kind, declaration] of parsed) {
171039
171198
  const known = this.placement.get(keyOf(owner, kind));
@@ -171177,6 +171336,27 @@ var require_sqlite_settings_addon = __commonJS({
171177
171336
  owner
171178
171337
  });
171179
171338
  }
171339
+ /**
171340
+ * All ops must resolve to ONE file (`records/transact-refused` `cross-file`
171341
+ * otherwise); that file's engine then checks the family and runs one SQLite
171342
+ * transaction.
171343
+ */
171344
+ async transact(input) {
171345
+ const owner = recordsCallerOf(input);
171346
+ const files = /* @__PURE__ */ new Map();
171347
+ for (const op of input.ops) {
171348
+ const database = this.placement.get(keyOf(owner, op.kind));
171349
+ if (database === void 0) throw new require_dist10.UnknownRecordKindError(`"${owner}" declared no kind "${op.kind}"`);
171350
+ files.set(database, [...files.get(database) ?? [], op.kind]);
171351
+ }
171352
+ if (files.size > 1) throw new require_dist10.TransactRefusedError(`cross-file: the ops span more than one database file (${[...files.entries()].map(([db, kinds]) => `${[...new Set(kinds)].join("+")}@${db}`).join(", ")}); a transaction lives in ONE file`);
171353
+ const first = input.ops[0];
171354
+ if (first === void 0) throw new require_dist10.InvalidRecordError("transact: no ops");
171355
+ return (await this.fileOf(owner, first.kind)).records("transact", {
171356
+ ...input,
171357
+ owner
171358
+ });
171359
+ }
171180
171360
  async allocateId(input) {
171181
171361
  const owner = recordsCallerOf(input);
171182
171362
  return (await this.fileOf(owner, input.kind)).records("allocateId", {
@@ -171434,7 +171614,7 @@ var require_sqlite_storage = __commonJS({
171434
171614
  });
171435
171615
  require_chunk_Cek0wNdY();
171436
171616
  var require_builtins_sqlite_storage_filesystem_storage_addon = require_filesystem_storage_addon();
171437
- var require_wal_maintenance = require_wal_maintenance_BQlvAduo();
171617
+ var require_wal_maintenance = require_wal_maintenance_BIpPCYDi();
171438
171618
  var require_builtins_sqlite_storage_sqlite_settings_addon = require_sqlite_settings_addon();
171439
171619
  var ConfigStore = class {
171440
171620
  db;
@@ -171518,7 +171698,7 @@ var require_storage_orchestrator_addon = __commonJS({
171518
171698
  [Symbol.toStringTag]: { value: "Module" }
171519
171699
  });
171520
171700
  var require_chunk = require_chunk_Cek0wNdY();
171521
- var require_dist10 = require_dist_Dwi4JA96();
171701
+ var require_dist10 = require_dist_QyW9hVO2();
171522
171702
  var require_read_all_rows$1 = require_read_all_rows_CVoO1ONM();
171523
171703
  var zod = require_zod();
171524
171704
  var node_crypto = __require("crypto");
@@ -176105,12 +176285,12 @@ var require_storage_orchestrator = __commonJS({
176105
176285
  }
176106
176286
  });
176107
176287
 
176108
- // ../system/dist/agent-https-CzA1AmyI.js
176109
- var require_agent_https_CzA1AmyI = __commonJS({
176110
- "../system/dist/agent-https-CzA1AmyI.js"(exports) {
176288
+ // ../system/dist/agent-https-OIvfjiTx.js
176289
+ var require_agent_https_OIvfjiTx = __commonJS({
176290
+ "../system/dist/agent-https-OIvfjiTx.js"(exports) {
176111
176291
  "use strict";
176112
176292
  var require_chunk = require_chunk_Cek0wNdY();
176113
- var require_dist10 = require_dist_Dwi4JA96();
176293
+ var require_dist10 = require_dist_QyW9hVO2();
176114
176294
  var require_x509_es = require_x509_es_C4cOo48M();
176115
176295
  var zod = require_zod();
176116
176296
  var node_crypto = __require("crypto");
@@ -177168,11 +177348,11 @@ var require_agent_https_CzA1AmyI = __commonJS({
177168
177348
  }
177169
177349
  });
177170
177350
 
177171
- // ../system/dist/constants-BYJ4ni7h.js
177172
- var require_constants_BYJ4ni7h = __commonJS({
177173
- "../system/dist/constants-BYJ4ni7h.js"(exports) {
177351
+ // ../system/dist/constants-CdgJF4V6.js
177352
+ var require_constants_CdgJF4V6 = __commonJS({
177353
+ "../system/dist/constants-CdgJF4V6.js"(exports) {
177174
177354
  "use strict";
177175
- var MESH_CA_KEY_REF = require_dist_Dwi4JA96().buildSecretRef({
177355
+ var MESH_CA_KEY_REF = require_dist_QyW9hVO2().buildSecretRef({
177176
177356
  owner: "system",
177177
177357
  scope: { kind: "global" },
177178
177358
  fieldPath: "meshCaKey"
@@ -194269,11 +194449,11 @@ var require_system_config_addon = __commonJS({
194269
194449
  [Symbol.toStringTag]: { value: "Module" }
194270
194450
  });
194271
194451
  var require_chunk = require_chunk_Cek0wNdY();
194272
- var require_dist10 = require_dist_Dwi4JA96();
194452
+ var require_dist10 = require_dist_QyW9hVO2();
194273
194453
  var require_safe_buffer$1 = require_safe_buffer_D3aoa_7X();
194274
194454
  var require_x509_es = require_x509_es_C4cOo48M();
194275
- var require_agent_https = require_agent_https_CzA1AmyI();
194276
- var require_constants$8 = require_constants_BYJ4ni7h();
194455
+ var require_agent_https = require_agent_https_OIvfjiTx();
194456
+ var require_constants$8 = require_constants_CdgJF4V6();
194277
194457
  var require_src$1 = require_src_CnAqG6EF();
194278
194458
  var zod = require_zod();
194279
194459
  var node_crypto = __require("crypto");
@@ -275325,7 +275505,7 @@ var require_winston_logging = __commonJS({
275325
275505
  [Symbol.toStringTag]: { value: "Module" }
275326
275506
  });
275327
275507
  var require_chunk = require_chunk_Cek0wNdY();
275328
- var require_dist10 = require_dist_Dwi4JA96();
275508
+ var require_dist10 = require_dist_QyW9hVO2();
275329
275509
  var require_formatter = require_formatter_DqAKDlvN();
275330
275510
  var require_log_file_read_protocol = require_log_file_read_protocol_D0WcLbIV();
275331
275511
  var node_path = __require("path");
@@ -283128,14 +283308,14 @@ var require_lib_8oZrELLm = __commonJS({
283128
283308
  }
283129
283309
  });
283130
283310
 
283131
- // ../system/dist/hub-mdns-ciao-3qdHbtyp.js
283132
- var require_hub_mdns_ciao_3qdHbtyp = __commonJS({
283133
- "../system/dist/hub-mdns-ciao-3qdHbtyp.js"(exports) {
283311
+ // ../system/dist/hub-mdns-ciao-CWkX17zX.js
283312
+ var require_hub_mdns_ciao_CWkX17zX = __commonJS({
283313
+ "../system/dist/hub-mdns-ciao-CWkX17zX.js"(exports) {
283134
283314
  "use strict";
283135
283315
  var require_chunk = require_chunk_Cek0wNdY();
283136
- var require_dist10 = require_dist_Dwi4JA96();
283316
+ var require_dist10 = require_dist_QyW9hVO2();
283137
283317
  var require_x509_es = require_x509_es_C4cOo48M();
283138
- var require_agent_https = require_agent_https_CzA1AmyI();
283318
+ var require_agent_https = require_agent_https_OIvfjiTx();
283139
283319
  var node_crypto = __require("crypto");
283140
283320
  var _camstack_types_node = require_node();
283141
283321
  var node_fs_promises = __require("fs/promises");
@@ -284147,12 +284327,12 @@ var require_platform_key_source_Di7HrlGR = __commonJS({
284147
284327
  }
284148
284328
  });
284149
284329
 
284150
- // ../system/dist/restore-archive-D1uxP8Eb.js
284151
- var require_restore_archive_D1uxP8Eb = __commonJS({
284152
- "../system/dist/restore-archive-D1uxP8Eb.js"(exports) {
284330
+ // ../system/dist/restore-archive-DMgpNgX5.js
284331
+ var require_restore_archive_DMgpNgX5 = __commonJS({
284332
+ "../system/dist/restore-archive-DMgpNgX5.js"(exports) {
284153
284333
  "use strict";
284154
284334
  var require_chunk = require_chunk_Cek0wNdY();
284155
- var require_dist10 = require_dist_Dwi4JA96();
284335
+ var require_dist10 = require_dist_QyW9hVO2();
284156
284336
  var zod = require_zod();
284157
284337
  var node_crypto = __require("crypto");
284158
284338
  var buffer = __require("buffer");
@@ -295393,9 +295573,9 @@ var require_dist3 = __commonJS({
295393
295573
  "use strict";
295394
295574
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
295395
295575
  var require_chunk = require_chunk_Cek0wNdY();
295396
- var require_dist10 = require_dist_Dwi4JA96();
295576
+ var require_dist10 = require_dist_QyW9hVO2();
295577
+ var require_device_ca = require_device_ca_DpvQ5wrb();
295397
295578
  var require_read_all_rows$1 = require_read_all_rows_CVoO1ONM();
295398
- var require_device_ca = require_device_ca_B_Txwl4W();
295399
295579
  var require_builtins_alerts_alerts_addon = require_alerts_addon();
295400
295580
  require_alerts();
295401
295581
  var require_builtins_calendars_calendars_addon = require_calendars_addon();
@@ -295419,21 +295599,21 @@ var require_dist3 = __commonJS({
295419
295599
  var require_builtins_native_metrics_native_metrics_addon = require_native_metrics_addon();
295420
295600
  var require_builtins_device_history_device_history_addon = require_device_history_addon();
295421
295601
  var require_builtins_sqlite_storage_filesystem_storage_addon = require_filesystem_storage_addon();
295422
- var require_wal_maintenance = require_wal_maintenance_BQlvAduo();
295602
+ var require_wal_maintenance = require_wal_maintenance_BIpPCYDi();
295423
295603
  var require_builtins_sqlite_storage_sqlite_settings_addon = require_sqlite_settings_addon();
295424
295604
  var require_builtins_sqlite_storage_index = require_sqlite_storage();
295425
295605
  var require_builtins_storage_orchestrator_storage_orchestrator_addon = require_storage_orchestrator_addon();
295426
295606
  require_storage_orchestrator();
295427
- var require_agent_https = require_agent_https_CzA1AmyI();
295428
- var require_constants15 = require_constants_BYJ4ni7h();
295607
+ var require_agent_https = require_agent_https_OIvfjiTx();
295608
+ var require_constants15 = require_constants_CdgJF4V6();
295429
295609
  var require_builtins_system_config_system_config_addon = require_system_config_addon();
295430
295610
  require_system_config();
295431
295611
  var require_builtins_winston_logging_index = require_winston_logging();
295432
295612
  var require_custom_action_registry = require_custom_action_registry_MRyes5j0();
295433
- var require_hub_mdns_ciao = require_hub_mdns_ciao_3qdHbtyp();
295613
+ var require_hub_mdns_ciao = require_hub_mdns_ciao_CWkX17zX();
295434
295614
  var require_platform_key_source = require_platform_key_source_Di7HrlGR();
295435
295615
  var require_resource_monitor = require_resource_monitor_mio9dSCT();
295436
- var require_restore_archive = require_restore_archive_D1uxP8Eb();
295616
+ var require_restore_archive = require_restore_archive_DMgpNgX5();
295437
295617
  var require_coral_accelerators = require_coral_accelerators_oUXmmbc2();
295438
295618
  var zod = require_zod();
295439
295619
  var node_crypto = __require("crypto");
@@ -308448,6 +308628,7 @@ var require_dist3 = __commonJS({
308448
308628
  histogram: (input) => r.histogram.query(input),
308449
308629
  aggregate: (input) => r.aggregate.query(input),
308450
308630
  deleteWhere: (input) => r.deleteWhere.mutate(input),
308631
+ transact: (input) => r.transact.mutate(input),
308451
308632
  deleteDevice: (input) => r.deleteDevice.mutate(input),
308452
308633
  allocateId: (input) => r.allocateId.mutate(input)
308453
308634
  };
@@ -318037,7 +318218,6 @@ var require_dist3 = __commonJS({
318037
318218
  exports.AgentMeshIdentityGate = AgentMeshIdentityGate;
318038
318219
  exports.AgentPairing = require_builtins_system_config_system_config_addon.AgentPairing;
318039
318220
  exports.AlertCenterAddon = require_builtins_alerts_alerts_addon.AlertCenterAddon;
318040
- exports.ApiKeyManager = require_builtins_local_auth_local_auth_addon.ApiKeyManager;
318041
318221
  exports.AuthAuditLog = require_builtins_local_auth_local_auth_addon.AuthAuditLog;
318042
318222
  exports.AuthManager = require_builtins_local_auth_local_auth_addon.AuthManager;
318043
318223
  exports.BackupDecryptError = require_restore_archive.BackupDecryptError;
@@ -318857,7 +319037,7 @@ var require_enums = __commonJS({
318857
319037
  "../types/dist/enums.js"(exports) {
318858
319038
  "use strict";
318859
319039
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
318860
- var require_event_category = require_event_category_kpu1bZMs();
319040
+ var require_event_category = require_event_category_7AwNbPjm();
318861
319041
  var EventSourceType = /* @__PURE__ */ (function(EventSourceType2) {
318862
319042
  EventSourceType2["Addon"] = "addon";
318863
319043
  EventSourceType2["Core"] = "core";
@@ -318877,8 +319057,8 @@ var require_dist4 = __commonJS({
318877
319057
  "../types/dist/index.js"(exports) {
318878
319058
  "use strict";
318879
319059
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
318880
- var require_sleep = require_sleep_Bo7fq491();
318881
- var require_event_category = require_event_category_kpu1bZMs();
319060
+ var require_sleep = require_sleep_CD18m9HF();
319061
+ var require_event_category = require_event_category_7AwNbPjm();
318882
319062
  var require_composition = require_composition_eoYYVfOp();
318883
319063
  var require_node_color2 = require_node_color();
318884
319064
  var require_err_msg = require_err_msg_BhVbr0NX();
@@ -323149,17 +323329,6 @@ var require_dist4 = __commonJS({
323149
323329
  createdAt: zod.z.number(),
323150
323330
  updatedAt: zod.z.number()
323151
323331
  });
323152
- var ApiKeyRecordSchema = zod.z.object({
323153
- id: zod.z.string(),
323154
- label: zod.z.string(),
323155
- isAdmin: zod.z.boolean().default(false),
323156
- allowedProviders: AllowedProviderSchema,
323157
- allowedDevices: AllowedDevicesSchema,
323158
- tokenHash: zod.z.string(),
323159
- tokenPrefix: zod.z.string(),
323160
- createdAt: zod.z.number(),
323161
- lastUsedAt: zod.z.number().optional()
323162
- });
323163
323332
  var ScopedTokenSchema = zod.z.object({
323164
323333
  id: zod.z.string(),
323165
323334
  userId: zod.z.string(),
@@ -329217,15 +329386,31 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
329217
329386
  var DeclareKindResultSchema = zod.z.object({
329218
329387
  kindId: zod.z.number().int(),
329219
329388
  state: RecordKindStateSchema,
329220
- createdIndexes: zod.z.array(zod.z.string()),
329221
- /**
329222
- * RETIRED (D900): always `null`. It carried the records-migration boot guard;
329223
- * it stays on the wire, null, because an addon built before the removal reads
329224
- * an ABSENT field as "adoption pending" and refuses to start.
329225
- */
329226
- adoptionPending: zod.z.null()
329389
+ createdIndexes: zod.z.array(zod.z.string())
329227
329390
  });
329228
329391
  var SecretRefsList = zod.z.array(zod.z.string());
329392
+ var RecordTransactOpSchema = zod.z.discriminatedUnion("op", [
329393
+ zod.z.object({
329394
+ op: zod.z.literal("put"),
329395
+ kind: require_sleep.RecordKindNameSchema,
329396
+ record: RecordInputSchema,
329397
+ ifRev: zod.z.number().int().min(0).optional()
329398
+ }),
329399
+ zod.z.object({
329400
+ op: zod.z.literal("patch"),
329401
+ kind: require_sleep.RecordKindNameSchema,
329402
+ id: RecordIdSchema,
329403
+ data: RecordBodySchema,
329404
+ at: zod.z.number().int().nullable().optional(),
329405
+ expiresAt: zod.z.number().int().nullable().optional(),
329406
+ ifRev: zod.z.number().int().min(1).optional()
329407
+ }),
329408
+ zod.z.object({
329409
+ op: zod.z.literal("delete"),
329410
+ kind: require_sleep.RecordKindNameSchema,
329411
+ id: RecordIdSchema
329412
+ })
329413
+ ]);
329229
329414
  var RecordSecretRefsSchema = zod.z.record(zod.z.string(), zod.z.record(zod.z.string(), zod.z.string()));
329230
329415
  var recordsCapability = {
329231
329416
  name: "records",
@@ -329357,6 +329542,22 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
329357
329542
  kind: "mutation",
329358
329543
  auth: "admin"
329359
329544
  }),
329545
+ /**
329546
+ * Several single-row writes (put / patch / delete) in ONE SQLite transaction:
329547
+ * all land or none does. Every op's kind must sit in one file and share one
329548
+ * `transactFamily` (`records/transact-refused` otherwise). Results are in op order.
329549
+ */
329550
+ transact: require_sleep.method(zod.z.object({ ops: zod.z.array(RecordTransactOpSchema).min(1).max(require_sleep.RECORD_BATCH_MAX) }), zod.z.object({
329551
+ results: zod.z.array(zod.z.object({
329552
+ rev: zod.z.number().int().nullable(),
329553
+ deleted: zod.z.boolean()
329554
+ })),
329555
+ releasedRefs: SecretRefsList,
329556
+ secretRefs: SecretRefsList
329557
+ }), {
329558
+ kind: "mutation",
329559
+ auth: "admin"
329560
+ }),
329360
329561
  /** The D865 hook body: every kind of this addon declared `deviceRemoval: 'delete'`. */
329361
329562
  deleteDevice: require_sleep.method(zod.z.object({
329362
329563
  deviceId: zod.z.number().int(),
@@ -356174,9 +356375,13 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
356174
356375
  "node-updating",
356175
356376
  "node-inference-unavailable",
356176
356377
  "detection-blind",
356378
+ "motion-noisy",
356379
+ "motion-calm",
356177
356380
  "recording-stalled",
356178
356381
  "recording-healthy",
356179
356382
  "recording-degraded",
356383
+ "device-attention-required",
356384
+ "device-attention-resolved",
356180
356385
  "storage-location-low",
356181
356386
  "storage-location-critical",
356182
356387
  "storage-location-ok",
@@ -357286,6 +357491,14 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
357286
357491
  value: "detection-blind",
357287
357492
  label: "Camera detecting nothing"
357288
357493
  },
357494
+ {
357495
+ value: "motion-noisy",
357496
+ label: "Camera motion constant, no subject"
357497
+ },
357498
+ {
357499
+ value: "motion-calm",
357500
+ label: "Camera motion calm again"
357501
+ },
357289
357502
  {
357290
357503
  value: "recording-stalled",
357291
357504
  label: "Recording stalled"
@@ -357298,6 +357511,14 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
357298
357511
  value: "recording-degraded",
357299
357512
  label: "Recording degraded (restart storm)"
357300
357513
  },
357514
+ {
357515
+ value: "device-attention-required",
357516
+ label: "Device needs attention"
357517
+ },
357518
+ {
357519
+ value: "device-attention-resolved",
357520
+ label: "Device attention resolved"
357521
+ },
357301
357522
  {
357302
357523
  value: "storage-location-low",
357303
357524
  label: "Storage location low"
@@ -370685,6 +370906,16 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
370685
370906
  powerState: zod.z.string().nullable(),
370686
370907
  saltLevel: DishwasherConsumableLevelSchema.nullable(),
370687
370908
  rinseAidLevel: DishwasherConsumableLevelSchema.nullable(),
370909
+ /**
370910
+ * True while the appliance asks for its filter to be cleaned (smart-filter, filter-system or
370911
+ * combined care-and-filter reminder raised); false when every such reminder reads clear; null
370912
+ * when none is reported. A cleared reminder is not an unknown one.
370913
+ */
370914
+ filterCleaningDue: zod.z.boolean().nullable(),
370915
+ /** True while the machine-care (descaling / cleaning-program) reminder is raised; false when clear; null when not reported. */
370916
+ machineCareDue: zod.z.boolean().nullable(),
370917
+ /** Program runs left before the machine-care reminder is due; null when the appliance does not say. */
370918
+ machineCareRemainingRuns: zod.z.number().int().nonnegative().nullable(),
370688
370919
  /** Option states: null when the appliance does not expose the option or has not said. */
370689
370920
  halfLoad: zod.z.boolean().nullable(),
370690
370921
  hygienePlus: zod.z.boolean().nullable(),
@@ -379178,16 +379409,6 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
379178
379409
  allowedDevices: zod.z.record(zod.z.string(), zod.z.union([zod.z.array(zod.z.string()), zod.z.literal("*")])).optional(),
379179
379410
  scopes: zod.z.array(TokenScopeSchema).optional()
379180
379411
  });
379181
- var ApiKeySummarySchema = zod.z.object({
379182
- id: zod.z.string(),
379183
- label: zod.z.string(),
379184
- isAdmin: zod.z.boolean().default(false),
379185
- allowedProviders: zod.z.union([zod.z.array(zod.z.string()), zod.z.literal("*")]).optional(),
379186
- allowedDevices: zod.z.record(zod.z.string(), zod.z.union([zod.z.array(zod.z.string()), zod.z.literal("*")])).optional(),
379187
- tokenPrefix: zod.z.string(),
379188
- createdAt: zod.z.number(),
379189
- lastUsedAt: zod.z.number().optional()
379190
- });
379191
379412
  var OauthSessionSummarySchema = zod.z.object({
379192
379413
  id: zod.z.string(),
379193
379414
  userId: zod.z.string(),
@@ -379268,12 +379489,6 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
379268
379489
  kind: "mutation",
379269
379490
  access: "view"
379270
379491
  }),
379271
- listApiKeys: require_sleep.method(zod.z.void(), zod.z.array(ApiKeySummarySchema), { auth: "admin" }),
379272
- revokeApiKey: require_sleep.method(zod.z.object({ id: zod.z.string() }), zod.z.object({ success: zod.z.literal(true) }), {
379273
- kind: "mutation",
379274
- auth: "admin",
379275
- access: "delete"
379276
- }),
379277
379492
  setupTotp: require_sleep.method(zod.z.object({ userId: zod.z.string() }), TotpSetupResultSchema, {
379278
379493
  kind: "mutation",
379279
379494
  auth: "admin",
@@ -389960,6 +390175,12 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
389960
390175
  addonId: null,
389961
390176
  access: "view"
389962
390177
  },
390178
+ "records.transact": {
390179
+ capName: "records",
390180
+ capScope: "system",
390181
+ addonId: null,
390182
+ access: "create"
390183
+ },
389963
390184
  "sceneMonitor.captureReference": {
389964
390185
  capName: "scene-monitor",
389965
390186
  capScope: "device",
@@ -391292,12 +391513,6 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
391292
391513
  addonId: null,
391293
391514
  access: "view"
391294
391515
  },
391295
- "userManagement.listApiKeys": {
391296
- capName: "user-management",
391297
- capScope: "system",
391298
- addonId: null,
391299
- access: "view"
391300
- },
391301
391516
  "userManagement.listExternalIdentities": {
391302
391517
  capName: "user-management",
391303
391518
  capScope: "system",
@@ -391352,12 +391567,6 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
391352
391567
  addonId: null,
391353
391568
  access: "create"
391354
391569
  },
391355
- "userManagement.revokeApiKey": {
391356
- capName: "user-management",
391357
- capScope: "system",
391358
- addonId: null,
391359
- access: "delete"
391360
- },
391361
391570
  "userManagement.revokeOauthSession": {
391362
391571
  capName: "user-management",
391363
391572
  capScope: "system",
@@ -399617,8 +399826,6 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
399617
399826
  resetPassword: (input) => dispatch("userManagement", "resetPassword", "mutation", input),
399618
399827
  setUserScopes: (input) => dispatch("userManagement", "setUserScopes", "mutation", input),
399619
399828
  validateCredentials: (input) => dispatch("userManagement", "validateCredentials", "mutation", input),
399620
- listApiKeys: (input) => dispatch("userManagement", "listApiKeys", "query", input),
399621
- revokeApiKey: (input) => dispatch("userManagement", "revokeApiKey", "mutation", input),
399622
399829
  setupTotp: (input) => dispatch("userManagement", "setupTotp", "mutation", input),
399623
399830
  confirmTotp: (input) => dispatch("userManagement", "confirmTotp", "mutation", input),
399624
399831
  disableTotp: (input) => dispatch("userManagement", "disableTotp", "mutation", input),
@@ -400056,9 +400263,9 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
400056
400263
  function systemEventFilterApplies(kind, filter) {
400057
400264
  switch (filter) {
400058
400265
  case "deviceIds":
400059
- return kind.startsWith("device-") || kind.startsWith("stream-") || kind === "detection-blind" || kind.startsWith("recording-") || kind === "alarm-triggered";
400266
+ return kind.startsWith("device-") || kind.startsWith("stream-") || kind === "detection-blind" || kind.startsWith("motion-") || kind.startsWith("recording-") || kind === "alarm-triggered";
400060
400267
  case "deviceTypes":
400061
- return kind.startsWith("device-") || kind === "detection-blind";
400268
+ return kind.startsWith("device-") || kind === "detection-blind" || kind.startsWith("motion-");
400062
400269
  case "nodeIds":
400063
400270
  return kind.startsWith("node-") || kind === "addon-crash-loop" || kind === "addon-update-available" || kind === "addon-updated" || kind === "server-update-available" || kind === "wrapper-update-available" || kind === "server-updated" || kind.startsWith("storage-location-") || kind.startsWith("alert-");
400064
400271
  case "packageNames":
@@ -400093,9 +400300,13 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
400093
400300
  "stream-online": "device-events",
400094
400301
  "stream-offline": "device-events",
400095
400302
  "detection-blind": "device-events",
400303
+ "motion-noisy": "device-events",
400304
+ "motion-calm": "device-events",
400096
400305
  "recording-stalled": "device-events",
400097
400306
  "recording-healthy": "device-events",
400098
400307
  "recording-degraded": "device-events",
400308
+ "device-attention-required": "device-events",
400309
+ "device-attention-resolved": "device-events",
400099
400310
  "node-online": "system",
400100
400311
  "node-offline": "system",
400101
400312
  "node-restarting": "system",
@@ -400189,6 +400400,12 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
400189
400400
  label: "Detecting nothing",
400190
400401
  kinds: ["detection-blind"]
400191
400402
  },
400403
+ {
400404
+ id: "motion-noise",
400405
+ family: "device-events",
400406
+ label: "Motion without a subject",
400407
+ kinds: ["motion-noisy", "motion-calm"]
400408
+ },
400192
400409
  {
400193
400410
  id: "recording",
400194
400411
  family: "device-events",
@@ -400199,6 +400416,12 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
400199
400416
  "recording-degraded"
400200
400417
  ]
400201
400418
  },
400419
+ {
400420
+ id: "device-attention",
400421
+ family: "device-events",
400422
+ label: "Needs attention",
400423
+ kinds: ["device-attention-required", "device-attention-resolved"]
400424
+ },
400202
400425
  {
400203
400426
  id: "nodes",
400204
400427
  family: "system",
@@ -401607,6 +401830,10 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
401607
401830
  if (severity === "error" && phase === "raised") return "alert-error";
401608
401831
  return null;
401609
401832
  }
401833
+ function deviceAttentionKind(severity, phase) {
401834
+ if (severity !== "critical") return null;
401835
+ return phase === "raised" ? "device-attention-required" : "device-attention-resolved";
401836
+ }
401610
401837
  function alertEpisodePayload(alert, phase, at) {
401611
401838
  const nodeId = alertNodeId(alert);
401612
401839
  return {
@@ -401640,6 +401867,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
401640
401867
  "alert-error",
401641
401868
  "alert-critical-resolved"
401642
401869
  ];
401870
+ var DEVICE_ATTENTION = ["device-attention-required", "device-attention-resolved"];
401643
401871
  var UPDATES = [
401644
401872
  "addon-update-available",
401645
401873
  "server-update-available",
@@ -401669,9 +401897,12 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
401669
401897
  "stream-online",
401670
401898
  "stream-offline",
401671
401899
  "detection-blind",
401900
+ "motion-noisy",
401901
+ "motion-calm",
401672
401902
  "recording-stalled",
401673
401903
  "recording-healthy",
401674
401904
  "recording-degraded",
401905
+ ...DEVICE_ATTENTION,
401675
401906
  ...ALARM
401676
401907
  ];
401677
401908
  var SUMMARISABLE = [...systemEventKindsOfFamily("device-events"), ...systemEventKindsOfFamily("system")];
@@ -402242,7 +402473,36 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
402242
402473
  families: ["rule"],
402243
402474
  fields: [...RULE_TEXT],
402244
402475
  kinds: ["system"],
402245
- systemEventKinds: ["detection-blind", "recording-stalled"]
402476
+ systemEventKinds: [
402477
+ "detection-blind",
402478
+ "motion-noisy",
402479
+ "motion-calm",
402480
+ "recording-stalled"
402481
+ ]
402482
+ },
402483
+ {
402484
+ name: "duty",
402485
+ label: "Motion share (%)",
402486
+ example: "55",
402487
+ group: "system",
402488
+ families: ["rule"],
402489
+ fields: [...RULE_TEXT],
402490
+ kinds: ["system"],
402491
+ systemEventKinds: ["motion-noisy", "motion-calm"]
402492
+ },
402493
+ {
402494
+ name: "sessions",
402495
+ label: "Detection sessions",
402496
+ example: "96",
402497
+ group: "system",
402498
+ families: ["rule"],
402499
+ fields: [...RULE_TEXT],
402500
+ kinds: ["system"],
402501
+ systemEventKinds: [
402502
+ "detection-blind",
402503
+ "motion-noisy",
402504
+ "motion-calm"
402505
+ ]
402246
402506
  },
402247
402507
  {
402248
402508
  name: "message",
@@ -402252,7 +402512,11 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
402252
402512
  families: ["rule"],
402253
402513
  fields: [...RULE_TEXT],
402254
402514
  kinds: ["system"],
402255
- systemEventKinds: ["recording-degraded", ...ALERT_EPISODE]
402515
+ systemEventKinds: [
402516
+ "recording-degraded",
402517
+ ...DEVICE_ATTENTION,
402518
+ ...ALERT_EPISODE
402519
+ ]
402256
402520
  },
402257
402521
  {
402258
402522
  name: "ruleName",
@@ -402496,7 +402760,11 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
402496
402760
  families: ["rule"],
402497
402761
  fields: [...RULE_TEXT],
402498
402762
  kinds: ["system"],
402499
- systemEventKinds: ["export-completed", ...ALERT_EPISODE]
402763
+ systemEventKinds: [
402764
+ "export-completed",
402765
+ ...DEVICE_ATTENTION,
402766
+ ...ALERT_EPISODE
402767
+ ]
402500
402768
  },
402501
402769
  {
402502
402770
  name: "severity",
@@ -402516,7 +402784,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
402516
402784
  families: ["rule"],
402517
402785
  fields: [...RULE_TEXT],
402518
402786
  kinds: ["system"],
402519
- systemEventKinds: [...ALERT_EPISODE]
402787
+ systemEventKinds: [...DEVICE_ATTENTION, ...ALERT_EPISODE]
402520
402788
  },
402521
402789
  {
402522
402790
  name: "source",
@@ -402536,7 +402804,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
402536
402804
  families: ["rule"],
402537
402805
  fields: [...RULE_TEXT],
402538
402806
  kinds: ["system"],
402539
- systemEventKinds: [...ALERT_EPISODE]
402807
+ systemEventKinds: [...DEVICE_ATTENTION, ...ALERT_EPISODE]
402540
402808
  },
402541
402809
  {
402542
402810
  name: "exportId",
@@ -402736,6 +403004,8 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
402736
403004
  "alert-critical",
402737
403005
  "alert-error",
402738
403006
  "alert-critical-resolved",
403007
+ "device-attention-required",
403008
+ "device-attention-resolved",
402739
403009
  "rule-broken",
402740
403010
  "rule-repaired"
402741
403011
  ];
@@ -402849,6 +403119,15 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
402849
403119
  snapshotLabel: "Tanks low or full now",
402850
403120
  snapshotSection: "tanks"
402851
403121
  },
403122
+ {
403123
+ id: "motion-noise",
403124
+ family: "device-events",
403125
+ label: "Motion without a subject (constant / calm again)",
403126
+ bad: ["motion-noisy"],
403127
+ recovery: ["motion-calm"],
403128
+ snapshotLabel: "Cameras with constant motion now",
403129
+ snapshotSection: null
403130
+ },
402852
403131
  {
402853
403132
  id: "recording-health",
402854
403133
  family: "device-events",
@@ -402858,6 +403137,15 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
402858
403137
  snapshotLabel: "Recordings stalled now",
402859
403138
  snapshotSection: null
402860
403139
  },
403140
+ {
403141
+ id: "device-attention",
403142
+ family: "device-events",
403143
+ label: "Device needs attention (raised / resolved)",
403144
+ bad: ["device-attention-required"],
403145
+ recovery: ["device-attention-resolved"],
403146
+ snapshotLabel: "Devices needing attention now",
403147
+ snapshotSection: null
403148
+ },
402861
403149
  {
402862
403150
  id: "node-connectivity",
402863
403151
  family: "system",
@@ -407035,8 +407323,6 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
407035
407323
  exports.AlertStatusSchema = AlertStatusSchema;
407036
407324
  exports.AmbientLightSensorStatusSchema = AmbientLightSensorStatusSchema;
407037
407325
  exports.AnalyticsLtsSeriesSchema = AnalyticsLtsSeriesSchema;
407038
- exports.ApiKeyRecordSchema = ApiKeyRecordSchema;
407039
- exports.ApiKeySummarySchema = ApiKeySummarySchema;
407040
407326
  exports.AppFlowPurposeSchema = AppFlowPurposeSchema;
407041
407327
  exports.AppLoginPathSchema = AppLoginPathSchema;
407042
407328
  exports.AppPageLangSchema = AppPageLangSchema;
@@ -408423,6 +408709,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
408423
408709
  exports.RecordSecretRefsSchema = RecordSecretRefsSchema;
408424
408710
  exports.RecordSecretUnavailableError = require_sleep.RecordSecretUnavailableError;
408425
408711
  exports.RecordTooLargeError = require_sleep.RecordTooLargeError;
408712
+ exports.RecordTransactOpSchema = RecordTransactOpSchema;
408426
408713
  exports.RecordTriggerSchema = RecordTriggerSchema;
408427
408714
  exports.RecordUniqueViolationError = require_sleep.RecordUniqueViolationError;
408428
408715
  exports.RecordViewSchema = RecordViewSchema;
@@ -408692,6 +408979,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
408692
408979
  exports.StorageTableSchema = StorageTableSchema;
408693
408980
  exports.StorageTestLocationResultSchema = TestLocationResultSchema;
408694
408981
  exports.StorageWriteChunkInputSchema = WriteChunkInputSchema;
408982
+ exports.StoredRecordKindDeclarationSchema = require_sleep.StoredRecordKindDeclarationSchema;
408695
408983
  exports.StreamCodecSchema = StreamCodecSchema;
408696
408984
  exports.StreamFormatSchema = StreamFormatSchema;
408697
408985
  exports.StreamNetworkStatsSchema = StreamNetworkStatsSchema;
@@ -408798,6 +409086,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
408798
409086
  exports.TrainingResultSchema = TrainingResultSchema;
408799
409087
  exports.TrainingSplitPlanSchema = TrainingSplitPlanSchema;
408800
409088
  exports.TrainingStageSchema = TrainingStageSchema;
409089
+ exports.TransactRefusedError = require_sleep.TransactRefusedError;
408801
409090
  exports.TransportPlaneCountsSchema = TransportPlaneCountsSchema;
408802
409091
  exports.TransportPlaneSchema = TransportPlaneSchema;
408803
409092
  exports.TurnServerSchema = TurnServerSchema;
@@ -408932,6 +409221,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
408932
409221
  exports.asRecordsError = require_sleep.asRecordsError;
408933
409222
  exports.asString = require_sleep.asString;
408934
409223
  exports.assertTimelapseCadences = assertTimelapseCadences;
409224
+ exports.assertTransactScope = require_sleep.assertTransactScope;
408935
409225
  exports.assertValidDeclaration = require_sleep.assertValidDeclaration;
408936
409226
  exports.assignNodeColorId = require_node_color2.assignNodeColorId;
408937
409227
  exports.audioAnalysisCapability = audioAnalysisCapability;
@@ -409129,6 +409419,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
409129
409419
  exports.detectionPipelineCapability = detectionPipelineCapability;
409130
409420
  exports.deviceAdminLinkCapability = deviceAdminLinkCapability;
409131
409421
  exports.deviceAdoptionCapability = deviceAdoptionCapability;
409422
+ exports.deviceAttentionKind = deviceAttentionKind;
409132
409423
  exports.deviceBackendToFormat = deviceBackendToFormat;
409133
409424
  exports.deviceCredentialsCapability = deviceCredentialsCapability;
409134
409425
  exports.deviceCustomAction = require_sleep.deviceCustomAction;
@@ -589765,6 +590056,7 @@ var require_addon_registry_service = __commonJS({
589765
590056
  histogram: (input) => provider().histogram(as(input)),
589766
590057
  aggregate: (input) => provider().aggregate(as(input)),
589767
590058
  deleteWhere: (input) => provider().deleteWhere(as(input)),
590059
+ transact: (input) => provider().transact(as(input)),
589768
590060
  deleteDevice: (input) => provider().deleteDevice(as(input)),
589769
590061
  allocateId: (input) => provider().allocateId(as(input))
589770
590062
  };