@camstack/types 1.2.397 → 1.2.398
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/addon.js +17 -2
- package/dist/addon.mjs +15 -3
- package/dist/capabilities/dishwasher.cap.d.ts +9 -0
- package/dist/capabilities/index.d.ts +2 -2
- package/dist/capabilities/notification-rules.cap.d.ts +92 -0
- package/dist/capabilities/osd-manager.cap.d.ts +24 -0
- package/dist/capabilities/records.cap.d.ts +67 -3
- package/dist/capabilities/storage-admin.cap.d.ts +0 -2
- package/dist/capabilities/user-management.cap.d.ts +2 -28
- package/dist/client.js +88 -9
- package/dist/client.mjs +88 -9
- package/dist/enums/event-category.d.ts +9 -0
- package/dist/enums.js +1 -1
- package/dist/enums.mjs +1 -1
- package/dist/{event-category-kpu1bZMs.js → event-category-7AwNbPjm.js} +9 -0
- package/dist/{event-category-7pZEBmVg.mjs → event-category-BfJwUd2S.mjs} +9 -0
- package/dist/generated/addon-api.d.ts +7 -14
- package/dist/generated/addon-cap-facts.d.ts +1 -1
- package/dist/generated/method-access-map.d.ts +1 -1
- package/dist/generated/system-proxy.d.ts +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +181 -61
- package/dist/index.mjs +177 -60
- package/dist/interfaces/auth.d.ts +1 -1
- package/dist/interfaces/event-bus.d.ts +24 -5
- package/dist/notification/alert-episode.d.ts +7 -0
- package/dist/records/errors.d.ts +9 -1
- package/dist/records/index.d.ts +1 -0
- package/dist/records/record-kind.d.ts +62 -2
- package/dist/records/records-access.d.ts +36 -1
- package/dist/records/transact-rules.d.ts +7 -0
- package/dist/schemas/auth-records.d.ts +0 -12
- package/dist/{sleep-Bo7fq491.js → sleep-CD18m9HF.js} +478 -311
- package/dist/{sleep-CueztlR1.mjs → sleep-DJFUfKvA.mjs} +461 -312
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as EventCategory } from "./event-category-
|
|
1
|
+
import { t as EventCategory } from "./event-category-BfJwUd2S.mjs";
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
//#region src/audio/audio-chunk-format.ts
|
|
4
4
|
/**
|
|
@@ -3227,7 +3227,8 @@ var RECORDS_ERROR_CODES = [
|
|
|
3227
3227
|
"invalid-record",
|
|
3228
3228
|
"declaration-refused",
|
|
3229
3229
|
"no-caller",
|
|
3230
|
-
"batch-too-large"
|
|
3230
|
+
"batch-too-large",
|
|
3231
|
+
"transact-refused"
|
|
3231
3232
|
];
|
|
3232
3233
|
var PREFIX = "records/";
|
|
3233
3234
|
/** The base of every records failure. `detail` is the human part of the message. */
|
|
@@ -3335,6 +3336,17 @@ var BatchTooLargeError = class extends RecordsError {
|
|
|
3335
3336
|
this.name = "BatchTooLargeError";
|
|
3336
3337
|
}
|
|
3337
3338
|
};
|
|
3339
|
+
/**
|
|
3340
|
+
* A `transact` the engine refuses before touching a row: an op on a kind the
|
|
3341
|
+
* caller did not declare in ONE file and ONE `transactFamily`. The detail names
|
|
3342
|
+
* which rule (`cross-file`, `cross-family`, `no-family`); it is never a silent split.
|
|
3343
|
+
*/
|
|
3344
|
+
var TransactRefusedError = class extends RecordsError {
|
|
3345
|
+
constructor(detail) {
|
|
3346
|
+
super("transact-refused", detail);
|
|
3347
|
+
this.name = "TransactRefusedError";
|
|
3348
|
+
}
|
|
3349
|
+
};
|
|
3338
3350
|
var FACTORIES = {
|
|
3339
3351
|
"rev-conflict": (d) => new RevConflictError(d),
|
|
3340
3352
|
"too-large": (d) => new RecordTooLargeError(d),
|
|
@@ -3349,7 +3361,8 @@ var FACTORIES = {
|
|
|
3349
3361
|
"invalid-record": (d) => new InvalidRecordError(d),
|
|
3350
3362
|
"declaration-refused": (d) => new DeclarationRefusedError(d),
|
|
3351
3363
|
"no-caller": (d) => new NoCallerError(d),
|
|
3352
|
-
"batch-too-large": (d) => new BatchTooLargeError(d)
|
|
3364
|
+
"batch-too-large": (d) => new BatchTooLargeError(d),
|
|
3365
|
+
"transact-refused": (d) => new TransactRefusedError(d)
|
|
3353
3366
|
};
|
|
3354
3367
|
function isCode(value) {
|
|
3355
3368
|
return RECORDS_ERROR_CODES.some((code) => code === value);
|
|
@@ -3640,8 +3653,7 @@ var EntryDescriptorSchema = z.object({
|
|
|
3640
3653
|
/** JSON Schema of the entry body; `secret: true` marks a password field. */
|
|
3641
3654
|
fields: z.record(z.string(), z.unknown())
|
|
3642
3655
|
}).strict();
|
|
3643
|
-
|
|
3644
|
-
var RecordKindDeclarationSchema = z.object({
|
|
3656
|
+
var RecordKindDeclarationShape = z.object({
|
|
3645
3657
|
database: z.enum(RECORD_DATABASES).default("settings"),
|
|
3646
3658
|
class: z.enum(RECORD_CLASSES),
|
|
3647
3659
|
writeTrigger: z.string().min(1),
|
|
@@ -3659,18 +3671,18 @@ var RecordKindDeclarationSchema = z.object({
|
|
|
3659
3671
|
secretPaths: z.array(z.string().min(1)).default([]),
|
|
3660
3672
|
/** The id key of each array that carries a secret (`{ headers: 'name' }`). */
|
|
3661
3673
|
secretArrayKeys: z.record(z.string(), z.string()).default({}),
|
|
3662
|
-
/**
|
|
3663
|
-
* RETIRED (D900): the legacy table a kind adopted from during the records
|
|
3664
|
-
* migration. Nothing declares it any more and nothing reads it; the schema
|
|
3665
|
-
* still ACCEPTS it because the catalog rows the migration wrote carry it
|
|
3666
|
-
* (an orphaned kind is never redeclared) and an addon built before the
|
|
3667
|
-
* removal still sends it. Never set it.
|
|
3668
|
-
*/
|
|
3669
|
-
adoptsFrom: z.string().min(1).optional(),
|
|
3670
3674
|
/** Kinds that must agree through `transact` sit in one file under one family name. */
|
|
3671
3675
|
transactFamily: z.string().min(1).optional(),
|
|
3672
3676
|
entry: EntryDescriptorSchema.optional()
|
|
3673
|
-
})
|
|
3677
|
+
});
|
|
3678
|
+
/** What crosses the wire from an addon: JSON only, no Zod. An unknown key is refused. */
|
|
3679
|
+
var RecordKindDeclarationSchema = RecordKindDeclarationShape.strict();
|
|
3680
|
+
/**
|
|
3681
|
+
* A declaration as the engine's catalog stored it: an unknown key is DROPPED,
|
|
3682
|
+
* because a row written by an older engine must never stop records from
|
|
3683
|
+
* starting. Only for rows read back from the catalog, never for input.
|
|
3684
|
+
*/
|
|
3685
|
+
var StoredRecordKindDeclarationSchema = RecordKindDeclarationShape;
|
|
3674
3686
|
/** The kind names: lower-case, dash separated, short enough for an index name. */
|
|
3675
3687
|
var RecordKindNameSchema = z.string().regex(/^[a-z][a-z0-9-]{0,47}$/);
|
|
3676
3688
|
/** Cross-field rules a declaration must satisfy. Throws {@link DeclarationRefusedError}. */
|
|
@@ -3761,6 +3773,25 @@ function declarationsOf(kinds) {
|
|
|
3761
3773
|
return Object.fromEntries(Object.entries(kinds).map(([name, kind]) => [name, kind.declaration]));
|
|
3762
3774
|
}
|
|
3763
3775
|
//#endregion
|
|
3776
|
+
//#region src/records/transact-rules.ts
|
|
3777
|
+
/**
|
|
3778
|
+
* The scope rule of `transact`, shared by the engine, the provider and the
|
|
3779
|
+
* in-memory records so they cannot disagree: every op's kind sits in ONE
|
|
3780
|
+
* database file, and when more than one kind is involved they all name the
|
|
3781
|
+
* SAME `transactFamily`. A refusal names the rule; nothing is split silently.
|
|
3782
|
+
*/
|
|
3783
|
+
/** Throws {@link TransactRefusedError} unless the kinds may share one transaction. */
|
|
3784
|
+
function assertTransactScope(members) {
|
|
3785
|
+
const byKind = /* @__PURE__ */ new Map();
|
|
3786
|
+
for (const m of members) byKind.set(m.kind, m);
|
|
3787
|
+
const kinds = [...byKind.values()];
|
|
3788
|
+
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`);
|
|
3789
|
+
if (kinds.length <= 1) return;
|
|
3790
|
+
const missing = kinds.filter((m) => m.declaration.transactFamily === void 0);
|
|
3791
|
+
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`);
|
|
3792
|
+
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(", ")})`);
|
|
3793
|
+
}
|
|
3794
|
+
//#endregion
|
|
3764
3795
|
//#region src/records/records-access.ts
|
|
3765
3796
|
function isRecord$2(value) {
|
|
3766
3797
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -3935,6 +3966,47 @@ var KindHandle = class {
|
|
|
3935
3966
|
};
|
|
3936
3967
|
});
|
|
3937
3968
|
}
|
|
3969
|
+
async txPut(input, opts = {}) {
|
|
3970
|
+
const checked = this.validate(input.data, input.id);
|
|
3971
|
+
const { body, rollback } = await this.storeSecrets(input.id, checked, "put");
|
|
3972
|
+
return {
|
|
3973
|
+
wire: {
|
|
3974
|
+
op: "put",
|
|
3975
|
+
kind: this.name,
|
|
3976
|
+
record: {
|
|
3977
|
+
...input,
|
|
3978
|
+
data: toBody(body)
|
|
3979
|
+
},
|
|
3980
|
+
...opts.ifRev === void 0 ? {} : { ifRev: opts.ifRev }
|
|
3981
|
+
},
|
|
3982
|
+
rollback
|
|
3983
|
+
};
|
|
3984
|
+
}
|
|
3985
|
+
async txPatch(id, partial, opts = {}) {
|
|
3986
|
+
const { body, rollback } = await this.storeSecrets(id, partial, "patch");
|
|
3987
|
+
return {
|
|
3988
|
+
wire: {
|
|
3989
|
+
op: "patch",
|
|
3990
|
+
kind: this.name,
|
|
3991
|
+
id,
|
|
3992
|
+
data: toBody(body),
|
|
3993
|
+
...opts.at === void 0 ? {} : { at: opts.at },
|
|
3994
|
+
...opts.expiresAt === void 0 ? {} : { expiresAt: opts.expiresAt },
|
|
3995
|
+
...opts.ifRev === void 0 ? {} : { ifRev: opts.ifRev }
|
|
3996
|
+
},
|
|
3997
|
+
rollback
|
|
3998
|
+
};
|
|
3999
|
+
}
|
|
4000
|
+
txDelete(id) {
|
|
4001
|
+
return {
|
|
4002
|
+
wire: {
|
|
4003
|
+
op: "delete",
|
|
4004
|
+
kind: this.name,
|
|
4005
|
+
id
|
|
4006
|
+
},
|
|
4007
|
+
rollback: async () => {}
|
|
4008
|
+
};
|
|
4009
|
+
}
|
|
3938
4010
|
async put(input, opts = {}) {
|
|
3939
4011
|
const checked = this.validate(input.data, input.id);
|
|
3940
4012
|
const { body, rollback } = await this.storeSecrets(input.id, checked, "put");
|
|
@@ -4089,6 +4161,23 @@ function createRecordsAccess(options) {
|
|
|
4089
4161
|
handles.set(definition, handle);
|
|
4090
4162
|
return handle;
|
|
4091
4163
|
},
|
|
4164
|
+
async transact(ops) {
|
|
4165
|
+
if (ops.length === 0) return [];
|
|
4166
|
+
const result = await call(() => options.transport.transact({ ops: ops.map((op) => op.wire) })).catch(async (err) => {
|
|
4167
|
+
for (const op of ops) await op.rollback();
|
|
4168
|
+
throw err;
|
|
4169
|
+
});
|
|
4170
|
+
const released = [...result.releasedRefs, ...result.secretRefs];
|
|
4171
|
+
if (released.length > 0 && options.secrets !== null) try {
|
|
4172
|
+
await options.secrets.delete(released);
|
|
4173
|
+
} catch (err) {
|
|
4174
|
+
options.logger?.warn("records: could not remove released keychain values", { meta: {
|
|
4175
|
+
count: released.length,
|
|
4176
|
+
error: err instanceof Error ? err.message : "unknown"
|
|
4177
|
+
} });
|
|
4178
|
+
}
|
|
4179
|
+
return result.results;
|
|
4180
|
+
},
|
|
4092
4181
|
async deleteDevice(deviceId, opts = {}) {
|
|
4093
4182
|
const result = await call(() => options.transport.deleteDevice({
|
|
4094
4183
|
deviceId,
|
|
@@ -4634,312 +4723,372 @@ function makeInMemoryRecords(owner = "spec", options = {}) {
|
|
|
4634
4723
|
secretRefs: refsOf(decl, gone)
|
|
4635
4724
|
};
|
|
4636
4725
|
};
|
|
4637
|
-
|
|
4638
|
-
|
|
4639
|
-
|
|
4640
|
-
|
|
4641
|
-
|
|
4642
|
-
|
|
4643
|
-
|
|
4644
|
-
|
|
4645
|
-
|
|
4646
|
-
|
|
4647
|
-
|
|
4648
|
-
|
|
4649
|
-
|
|
4650
|
-
|
|
4651
|
-
|
|
4652
|
-
|
|
4653
|
-
|
|
4654
|
-
|
|
4655
|
-
|
|
4656
|
-
|
|
4657
|
-
|
|
4658
|
-
|
|
4659
|
-
|
|
4660
|
-
|
|
4661
|
-
|
|
4662
|
-
|
|
4663
|
-
|
|
4664
|
-
|
|
4665
|
-
|
|
4666
|
-
|
|
4667
|
-
|
|
4668
|
-
|
|
4669
|
-
|
|
4670
|
-
|
|
4671
|
-
|
|
4672
|
-
|
|
4673
|
-
|
|
4674
|
-
|
|
4675
|
-
|
|
4676
|
-
|
|
4677
|
-
|
|
4678
|
-
|
|
4679
|
-
|
|
4680
|
-
|
|
4681
|
-
|
|
4682
|
-
|
|
4683
|
-
|
|
4684
|
-
|
|
4726
|
+
const transport = {
|
|
4727
|
+
declareKinds: async ({ kinds }) => {
|
|
4728
|
+
const out = {};
|
|
4729
|
+
for (const [name, raw] of Object.entries(kinds)) {
|
|
4730
|
+
const decl = RecordKindDeclarationSchema.parse(raw);
|
|
4731
|
+
assertValidDeclaration(name, decl);
|
|
4732
|
+
const prior = decls.get(name);
|
|
4733
|
+
if (prior !== void 0) assertAdditive(name, prior, decl);
|
|
4734
|
+
const kindId = kindIds.get(name) ?? kindIds.size + 1;
|
|
4735
|
+
kindIds.set(name, kindId);
|
|
4736
|
+
const created = decl.indexes.filter((i) => prior?.indexes.every((p) => p.name !== i.name) ?? true).map((i) => i.name);
|
|
4737
|
+
const state = prior === void 0 ? "created" : JSON.stringify(prior) === JSON.stringify(decl) ? "unchanged" : "updated";
|
|
4738
|
+
decls.set(name, decl);
|
|
4739
|
+
out[name] = {
|
|
4740
|
+
kindId,
|
|
4741
|
+
state,
|
|
4742
|
+
createdIndexes: created
|
|
4743
|
+
};
|
|
4744
|
+
}
|
|
4745
|
+
return { kinds: out };
|
|
4746
|
+
},
|
|
4747
|
+
get: async ({ kind, id }) => {
|
|
4748
|
+
reading();
|
|
4749
|
+
const decl = declOf(kind);
|
|
4750
|
+
const row = table(kind).get(id);
|
|
4751
|
+
return row === void 0 ? null : view(decl, row);
|
|
4752
|
+
},
|
|
4753
|
+
getMany: async ({ kind, ids }) => {
|
|
4754
|
+
reading();
|
|
4755
|
+
const decl = declOf(kind);
|
|
4756
|
+
return [...new Set(ids)].sort((a, b) => compareSql(a, b)).flatMap((id) => {
|
|
4757
|
+
const row = table(kind).get(id);
|
|
4758
|
+
return row === void 0 ? [] : [view(decl, row)];
|
|
4759
|
+
});
|
|
4760
|
+
},
|
|
4761
|
+
secretRefs: async ({ kind, ids }) => {
|
|
4762
|
+
reading();
|
|
4763
|
+
const decl = declOf(kind);
|
|
4764
|
+
const out = {};
|
|
4765
|
+
for (const id of ids) {
|
|
4766
|
+
const row = table(kind).get(id);
|
|
4767
|
+
if (row === void 0) continue;
|
|
4768
|
+
const refs = Object.fromEntries(markersOf(decl, row.data));
|
|
4769
|
+
if (Object.keys(refs).length > 0) out[id] = refs;
|
|
4770
|
+
}
|
|
4771
|
+
return out;
|
|
4772
|
+
},
|
|
4773
|
+
put: async ({ kind, record, ifRev }) => {
|
|
4774
|
+
writing();
|
|
4775
|
+
const written = writeRecord(kind, record, ifRev, now());
|
|
4776
|
+
afterWrite(kind, [record.deviceId]);
|
|
4777
|
+
return {
|
|
4778
|
+
rev: written.rev,
|
|
4779
|
+
releasedRefs: [...written.released]
|
|
4780
|
+
};
|
|
4781
|
+
},
|
|
4782
|
+
putMany: async ({ kind, records }) => {
|
|
4783
|
+
writing();
|
|
4784
|
+
declOf(kind);
|
|
4785
|
+
if (records.length > 1e3) throw new BatchTooLargeError(`${records.length} records exceed ${RECORD_BATCH_MAX}`);
|
|
4786
|
+
const bytes = records.reduce((sum, r) => sum + Buffer.byteLength(JSON.stringify(r.data), "utf8"), 0);
|
|
4787
|
+
if (bytes > 4194304) throw new BatchTooLargeError(`${bytes} bytes exceed ${RECORD_BATCH_MAX_BYTES}`);
|
|
4788
|
+
const nowMs = now();
|
|
4789
|
+
const before = new Map(table(kind));
|
|
4790
|
+
const ridBefore = nextRid;
|
|
4791
|
+
const released = [];
|
|
4792
|
+
try {
|
|
4793
|
+
for (const rec of records) released.push(...writeRecord(kind, rec, void 0, nowMs).released);
|
|
4794
|
+
} catch (err) {
|
|
4795
|
+
tables.set(kind, before);
|
|
4796
|
+
nextRid = ridBefore;
|
|
4797
|
+
throw err;
|
|
4798
|
+
}
|
|
4799
|
+
let top = -1;
|
|
4800
|
+
for (const r of records) if (/^\d{1,15}$/.test(r.id)) top = Math.max(top, Number(r.id));
|
|
4801
|
+
if (top >= 0) sequences.set(kind, Math.max(sequences.get(kind) ?? 0, top + 1));
|
|
4802
|
+
afterWrite(kind, records.map((r) => r.deviceId));
|
|
4803
|
+
return {
|
|
4804
|
+
count: records.length,
|
|
4805
|
+
releasedRefs: released
|
|
4806
|
+
};
|
|
4807
|
+
},
|
|
4808
|
+
patch: async (input) => {
|
|
4809
|
+
writing();
|
|
4810
|
+
const decl = declOf(input.kind);
|
|
4811
|
+
if (input.at !== void 0 && decl.at !== "required") throw new InvalidRecordError(`${input.kind}: declared at: "none"`);
|
|
4812
|
+
if (input.at === null) throw new InvalidRecordError(`${input.kind}: "at" cannot be removed`);
|
|
4813
|
+
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)`);
|
|
4814
|
+
if (input.expiresAt !== void 0 && "ttlMs" in decl.retention) throw new InvalidRecordError(`${input.kind}: expiresAt is set by the engine`);
|
|
4815
|
+
const before = table(input.kind).get(input.id);
|
|
4816
|
+
const checked = enforceSecrets(owner, input.kind, decl, input.id, input.data, before?.data ?? null, "patch");
|
|
4817
|
+
if (before === void 0) throw new RecordNotFoundError(`${input.kind}/${input.id}: no such row`);
|
|
4818
|
+
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}`);
|
|
4819
|
+
const merged = jsonCopy(mergePatch(before.data, jsonCopy(checked.body)));
|
|
4820
|
+
const size = [...JSON.stringify(merged)].length;
|
|
4821
|
+
if (size > decl.maxDataBytes) throw new RecordTooLargeError(`${input.kind}/${input.id}: the patched body is ${size} bytes, over maxDataBytes ${decl.maxDataBytes}`);
|
|
4822
|
+
assertUnique(input.kind, decl, input.id, merged);
|
|
4823
|
+
const rev = before.rev + 1;
|
|
4824
|
+
store(input.kind, before, {
|
|
4825
|
+
...before,
|
|
4826
|
+
at: input.at ?? before.at,
|
|
4827
|
+
expiresAt: input.expiresAt === void 0 ? before.expiresAt : input.expiresAt,
|
|
4828
|
+
rev,
|
|
4829
|
+
updatedAt: now(),
|
|
4830
|
+
data: merged
|
|
4831
|
+
});
|
|
4832
|
+
const kept = new Set(markersOf(decl, merged).values());
|
|
4833
|
+
return {
|
|
4834
|
+
rev,
|
|
4835
|
+
releasedRefs: [...markersOf(decl, before.data).values()].filter((r) => !kept.has(r))
|
|
4836
|
+
};
|
|
4837
|
+
},
|
|
4838
|
+
delete: async ({ kind, id }) => {
|
|
4839
|
+
writing();
|
|
4840
|
+
const decl = declOf(kind);
|
|
4841
|
+
const row = table(kind).get(id);
|
|
4842
|
+
if (row === void 0) return {
|
|
4843
|
+
deleted: false,
|
|
4844
|
+
secretRefs: []
|
|
4845
|
+
};
|
|
4846
|
+
table(kind).delete(id);
|
|
4847
|
+
return {
|
|
4848
|
+
deleted: true,
|
|
4849
|
+
secretRefs: refsOf(decl, [row])
|
|
4850
|
+
};
|
|
4851
|
+
},
|
|
4852
|
+
deleteMany: async ({ kind, ids }) => {
|
|
4853
|
+
writing();
|
|
4854
|
+
const wanted = new Set(ids);
|
|
4855
|
+
return removeWhere(kind, (row) => wanted.has(row.id));
|
|
4856
|
+
},
|
|
4857
|
+
query: async (q) => {
|
|
4858
|
+
reading();
|
|
4859
|
+
const decl = declOf(q.kind);
|
|
4860
|
+
queries.push({
|
|
4861
|
+
kind: q.kind,
|
|
4862
|
+
limit: q.limit
|
|
4863
|
+
});
|
|
4864
|
+
assertWindowAllowed(q.kind, decl, q);
|
|
4865
|
+
const desc = q.desc === true;
|
|
4866
|
+
const dir = desc ? "DESC" : "ASC";
|
|
4867
|
+
const where = planWhere(q.kind, decl, q.where, { allowIn: false });
|
|
4868
|
+
const cursor = q.cursor === void 0 ? void 0 : decodeCursor(q.cursor);
|
|
4869
|
+
let rows = [...table(q.kind).values()].filter((r) => inWindow(r, q));
|
|
4870
|
+
let keysOf;
|
|
4871
|
+
let keyCount;
|
|
4872
|
+
let tag;
|
|
4873
|
+
if (where !== null) {
|
|
4874
|
+
if (q.order !== void 0) throw new InvalidRecordError(`${q.kind}: with a where the order is the index's; drop "order"`);
|
|
4875
|
+
const fields = where.orderFields;
|
|
4876
|
+
keysOf = (row) => [...fields.map((f) => extractField(row.data, f)), row.rid];
|
|
4877
|
+
keyCount = fields.length;
|
|
4878
|
+
tag = `rx:${where.indexName}:${dir}`;
|
|
4879
|
+
rows = rows.filter((r) => where.matches(r.data));
|
|
4880
|
+
if (cursor !== void 0) {
|
|
4881
|
+
assertCursor(cursor, tag, fields.length + 1);
|
|
4882
|
+
rows = rows.filter((r) => rowValueAfter(keysOf(r), cursor.values, desc));
|
|
4883
|
+
}
|
|
4884
|
+
} else {
|
|
4885
|
+
const order = q.order ?? (decl.at === "required" ? "at" : "id");
|
|
4886
|
+
keyCount = 1;
|
|
4887
|
+
if (order === "at") {
|
|
4888
|
+
if (decl.at !== "required") throw new InvalidRecordError(`${q.kind}: declared at: "none", it has no time order - use order: "id"`);
|
|
4889
|
+
keysOf = (row) => [row.at, row.rid];
|
|
4890
|
+
tag = `at:${dir}`;
|
|
4891
|
+
if (cursor !== void 0) {
|
|
4892
|
+
assertCursor(cursor, tag, 2);
|
|
4893
|
+
rows = rows.filter((r) => rowValueAfter(keysOf(r), cursor.values, desc));
|
|
4685
4894
|
}
|
|
4686
|
-
|
|
4687
|
-
|
|
4688
|
-
|
|
4689
|
-
|
|
4690
|
-
|
|
4691
|
-
|
|
4692
|
-
|
|
4693
|
-
|
|
4694
|
-
releasedRefs: [...written.released]
|
|
4695
|
-
};
|
|
4696
|
-
},
|
|
4697
|
-
putMany: async ({ kind, records }) => {
|
|
4698
|
-
writing();
|
|
4699
|
-
declOf(kind);
|
|
4700
|
-
if (records.length > 1e3) throw new BatchTooLargeError(`${records.length} records exceed ${RECORD_BATCH_MAX}`);
|
|
4701
|
-
const bytes = records.reduce((sum, r) => sum + Buffer.byteLength(JSON.stringify(r.data), "utf8"), 0);
|
|
4702
|
-
if (bytes > 4194304) throw new BatchTooLargeError(`${bytes} bytes exceed ${RECORD_BATCH_MAX_BYTES}`);
|
|
4703
|
-
const nowMs = now();
|
|
4704
|
-
const before = new Map(table(kind));
|
|
4705
|
-
const ridBefore = nextRid;
|
|
4706
|
-
const released = [];
|
|
4707
|
-
try {
|
|
4708
|
-
for (const rec of records) released.push(...writeRecord(kind, rec, void 0, nowMs).released);
|
|
4709
|
-
} catch (err) {
|
|
4710
|
-
tables.set(kind, before);
|
|
4711
|
-
nextRid = ridBefore;
|
|
4712
|
-
throw err;
|
|
4895
|
+
} else {
|
|
4896
|
+
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")`);
|
|
4897
|
+
keysOf = (row) => [row.id, row.rid];
|
|
4898
|
+
tag = `id:${dir}`;
|
|
4899
|
+
if (cursor !== void 0) {
|
|
4900
|
+
assertCursor(cursor, tag, 2);
|
|
4901
|
+
const last = cursor.values[0] ?? null;
|
|
4902
|
+
rows = rows.filter((r) => rowValueAfter([r.id], [last], desc));
|
|
4713
4903
|
}
|
|
4714
|
-
|
|
4715
|
-
|
|
4716
|
-
|
|
4717
|
-
|
|
4718
|
-
|
|
4719
|
-
|
|
4720
|
-
|
|
4721
|
-
|
|
4722
|
-
|
|
4723
|
-
|
|
4724
|
-
|
|
4725
|
-
const
|
|
4726
|
-
if (
|
|
4727
|
-
|
|
4728
|
-
|
|
4729
|
-
|
|
4730
|
-
|
|
4731
|
-
|
|
4732
|
-
|
|
4733
|
-
|
|
4734
|
-
|
|
4735
|
-
|
|
4736
|
-
|
|
4737
|
-
|
|
4738
|
-
|
|
4739
|
-
|
|
4740
|
-
|
|
4741
|
-
|
|
4742
|
-
|
|
4743
|
-
|
|
4744
|
-
|
|
4745
|
-
|
|
4904
|
+
}
|
|
4905
|
+
}
|
|
4906
|
+
rows.sort((a, b) => (desc ? -1 : 1) * compareKeys(keysOf(a), keysOf(b)));
|
|
4907
|
+
const page = rows.slice(0, q.limit);
|
|
4908
|
+
const more = rows.length > q.limit;
|
|
4909
|
+
const last = page.at(-1);
|
|
4910
|
+
let nextCursor = null;
|
|
4911
|
+
if (more && last !== void 0) {
|
|
4912
|
+
const all = keysOf(last);
|
|
4913
|
+
const keys = [];
|
|
4914
|
+
for (let i = 0; i < keyCount; i += 1) {
|
|
4915
|
+
const value = all[i];
|
|
4916
|
+
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`);
|
|
4917
|
+
keys.push(value);
|
|
4918
|
+
}
|
|
4919
|
+
keys.push(last.rid);
|
|
4920
|
+
nextCursor = encodeCursor(tag, keys);
|
|
4921
|
+
}
|
|
4922
|
+
return {
|
|
4923
|
+
records: page.map((r) => view(decl, r)),
|
|
4924
|
+
nextCursor
|
|
4925
|
+
};
|
|
4926
|
+
},
|
|
4927
|
+
count: async (q) => {
|
|
4928
|
+
reading();
|
|
4929
|
+
const decl = declOf(q.kind);
|
|
4930
|
+
assertWindowAllowed(q.kind, decl, q);
|
|
4931
|
+
const where = planWhere(q.kind, decl, q.where, { allowIn: true });
|
|
4932
|
+
let n = 0;
|
|
4933
|
+
for (const row of table(q.kind).values()) if (inWindow(row, q) && (where === null || where.matches(row.data))) n += 1;
|
|
4934
|
+
return { count: n };
|
|
4935
|
+
},
|
|
4936
|
+
histogram: async (q) => {
|
|
4937
|
+
reading();
|
|
4938
|
+
const decl = declOf(q.kind);
|
|
4939
|
+
assertWindowAllowed(q.kind, decl, {
|
|
4940
|
+
deviceId: q.deviceId,
|
|
4941
|
+
atFrom: q.from
|
|
4942
|
+
});
|
|
4943
|
+
if (!(q.to > q.from)) throw new InvalidRecordError(`${q.kind}: histogram needs from < to`);
|
|
4944
|
+
if (Math.ceil((q.to - q.from) / q.bucketMs) > 1e4) throw new InvalidRecordError(`${q.kind}: histogram would exceed ${HISTOGRAM_MAX_BUCKETS} buckets`);
|
|
4945
|
+
const from = Math.floor(q.from);
|
|
4946
|
+
const to = Math.ceil(q.to);
|
|
4947
|
+
const step = Math.trunc(q.bucketMs);
|
|
4948
|
+
const counts = /* @__PURE__ */ new Map();
|
|
4949
|
+
for (const row of table(q.kind).values()) {
|
|
4950
|
+
if (q.deviceId !== void 0 && row.deviceId !== q.deviceId) continue;
|
|
4951
|
+
if (row.at === null || row.at < from || row.at >= to) continue;
|
|
4952
|
+
const b = Math.trunc((row.at - from) / step);
|
|
4953
|
+
counts.set(b, (counts.get(b) ?? 0) + 1);
|
|
4954
|
+
}
|
|
4955
|
+
return { buckets: [...counts.entries()].sort(([a], [b]) => a - b).map(([b, count]) => ({
|
|
4956
|
+
bucketStart: from + b * q.bucketMs,
|
|
4957
|
+
count
|
|
4958
|
+
})) };
|
|
4959
|
+
},
|
|
4960
|
+
aggregate: async (q) => {
|
|
4961
|
+
reading();
|
|
4962
|
+
const decl = declOf(q.kind);
|
|
4963
|
+
if (q.op !== "count" && q.field === void 0) throw new InvalidRecordError(`${q.kind}: ${q.op} needs a field`);
|
|
4964
|
+
const extra = [q.field, q.groupBy].filter((f) => f !== void 0);
|
|
4965
|
+
if (extra.length === 0 && q.where === void 0) throw new InvalidRecordError(`${q.kind}: a count with no field and no groupBy is "count"`);
|
|
4966
|
+
const where = planWhere(q.kind, decl, q.where, {
|
|
4967
|
+
allowIn: true,
|
|
4968
|
+
extraFields: extra,
|
|
4969
|
+
groupBy: q.groupBy
|
|
4970
|
+
});
|
|
4971
|
+
if (where === null) throw new InvalidRecordError(`${q.kind}: aggregate has nothing to read`);
|
|
4972
|
+
const rows = [...table(q.kind).values()].filter((r) => where.matches(r.data));
|
|
4973
|
+
const groups = /* @__PURE__ */ new Map();
|
|
4974
|
+
if (q.groupBy === void 0) groups.set(null, rows);
|
|
4975
|
+
else {
|
|
4976
|
+
const by = q.groupBy;
|
|
4977
|
+
for (const row of rows) {
|
|
4978
|
+
const g = extractField(row.data, by);
|
|
4979
|
+
groups.set(g, [...groups.get(g) ?? [], row]);
|
|
4980
|
+
}
|
|
4981
|
+
}
|
|
4982
|
+
return { rows: [...groups.entries()].sort(([a], [b]) => compareSql(a, b)).map(([group, members]) => ({
|
|
4983
|
+
group,
|
|
4984
|
+
value: aggregateOf(q.op, q.field, members)
|
|
4985
|
+
})) };
|
|
4986
|
+
},
|
|
4987
|
+
deleteWhere: async (q) => {
|
|
4988
|
+
writing();
|
|
4989
|
+
const decl = declOf(q.kind);
|
|
4990
|
+
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"`);
|
|
4991
|
+
assertWindowAllowed(q.kind, decl, {
|
|
4992
|
+
deviceId: q.deviceId,
|
|
4993
|
+
atFrom: q.atBefore
|
|
4994
|
+
});
|
|
4995
|
+
const where = planWhere(q.kind, decl, q.where, { allowIn: true });
|
|
4996
|
+
return removeWhere(q.kind, (row) => {
|
|
4997
|
+
if (where !== null && !where.matches(row.data)) return false;
|
|
4998
|
+
if (q.deviceId !== void 0 && row.deviceId !== q.deviceId) return false;
|
|
4999
|
+
if (q.atBefore !== void 0 && (row.at === null || row.at >= q.atBefore)) return false;
|
|
5000
|
+
return true;
|
|
5001
|
+
});
|
|
5002
|
+
},
|
|
5003
|
+
transact: async ({ ops }) => {
|
|
5004
|
+
writing();
|
|
5005
|
+
assertTransactScope(ops.map((op) => ({
|
|
5006
|
+
kind: op.kind,
|
|
5007
|
+
declaration: declOf(op.kind)
|
|
5008
|
+
})));
|
|
5009
|
+
const before = new Map([...tables].map(([name, rows]) => [name, new Map(rows)]));
|
|
5010
|
+
const ridBefore = nextRid;
|
|
5011
|
+
const results = [];
|
|
5012
|
+
const releasedRefs = [];
|
|
5013
|
+
const secretRefs = [];
|
|
5014
|
+
try {
|
|
5015
|
+
for (const op of ops) if (op.op === "put") {
|
|
5016
|
+
const r = await transport.put({
|
|
5017
|
+
kind: op.kind,
|
|
5018
|
+
record: op.record,
|
|
5019
|
+
...op.ifRev === void 0 ? {} : { ifRev: op.ifRev }
|
|
4746
5020
|
});
|
|
4747
|
-
|
|
4748
|
-
|
|
4749
|
-
rev,
|
|
4750
|
-
|
|
4751
|
-
};
|
|
4752
|
-
},
|
|
4753
|
-
delete: async ({ kind, id }) => {
|
|
4754
|
-
writing();
|
|
4755
|
-
const decl = declOf(kind);
|
|
4756
|
-
const row = table(kind).get(id);
|
|
4757
|
-
if (row === void 0) return {
|
|
4758
|
-
deleted: false,
|
|
4759
|
-
secretRefs: []
|
|
4760
|
-
};
|
|
4761
|
-
table(kind).delete(id);
|
|
4762
|
-
return {
|
|
4763
|
-
deleted: true,
|
|
4764
|
-
secretRefs: refsOf(decl, [row])
|
|
4765
|
-
};
|
|
4766
|
-
},
|
|
4767
|
-
deleteMany: async ({ kind, ids }) => {
|
|
4768
|
-
writing();
|
|
4769
|
-
const wanted = new Set(ids);
|
|
4770
|
-
return removeWhere(kind, (row) => wanted.has(row.id));
|
|
4771
|
-
},
|
|
4772
|
-
query: async (q) => {
|
|
4773
|
-
reading();
|
|
4774
|
-
const decl = declOf(q.kind);
|
|
4775
|
-
queries.push({
|
|
4776
|
-
kind: q.kind,
|
|
4777
|
-
limit: q.limit
|
|
5021
|
+
releasedRefs.push(...r.releasedRefs);
|
|
5022
|
+
results.push({
|
|
5023
|
+
rev: r.rev,
|
|
5024
|
+
deleted: false
|
|
4778
5025
|
});
|
|
4779
|
-
|
|
4780
|
-
const
|
|
4781
|
-
|
|
4782
|
-
|
|
4783
|
-
|
|
4784
|
-
|
|
4785
|
-
|
|
4786
|
-
|
|
4787
|
-
let tag;
|
|
4788
|
-
if (where !== null) {
|
|
4789
|
-
if (q.order !== void 0) throw new InvalidRecordError(`${q.kind}: with a where the order is the index's; drop "order"`);
|
|
4790
|
-
const fields = where.orderFields;
|
|
4791
|
-
keysOf = (row) => [...fields.map((f) => extractField(row.data, f)), row.rid];
|
|
4792
|
-
keyCount = fields.length;
|
|
4793
|
-
tag = `rx:${where.indexName}:${dir}`;
|
|
4794
|
-
rows = rows.filter((r) => where.matches(r.data));
|
|
4795
|
-
if (cursor !== void 0) {
|
|
4796
|
-
assertCursor(cursor, tag, fields.length + 1);
|
|
4797
|
-
rows = rows.filter((r) => rowValueAfter(keysOf(r), cursor.values, desc));
|
|
4798
|
-
}
|
|
4799
|
-
} else {
|
|
4800
|
-
const order = q.order ?? (decl.at === "required" ? "at" : "id");
|
|
4801
|
-
keyCount = 1;
|
|
4802
|
-
if (order === "at") {
|
|
4803
|
-
if (decl.at !== "required") throw new InvalidRecordError(`${q.kind}: declared at: "none", it has no time order - use order: "id"`);
|
|
4804
|
-
keysOf = (row) => [row.at, row.rid];
|
|
4805
|
-
tag = `at:${dir}`;
|
|
4806
|
-
if (cursor !== void 0) {
|
|
4807
|
-
assertCursor(cursor, tag, 2);
|
|
4808
|
-
rows = rows.filter((r) => rowValueAfter(keysOf(r), cursor.values, desc));
|
|
4809
|
-
}
|
|
4810
|
-
} else {
|
|
4811
|
-
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")`);
|
|
4812
|
-
keysOf = (row) => [row.id, row.rid];
|
|
4813
|
-
tag = `id:${dir}`;
|
|
4814
|
-
if (cursor !== void 0) {
|
|
4815
|
-
assertCursor(cursor, tag, 2);
|
|
4816
|
-
const last = cursor.values[0] ?? null;
|
|
4817
|
-
rows = rows.filter((r) => rowValueAfter([r.id], [last], desc));
|
|
4818
|
-
}
|
|
4819
|
-
}
|
|
4820
|
-
}
|
|
4821
|
-
rows.sort((a, b) => (desc ? -1 : 1) * compareKeys(keysOf(a), keysOf(b)));
|
|
4822
|
-
const page = rows.slice(0, q.limit);
|
|
4823
|
-
const more = rows.length > q.limit;
|
|
4824
|
-
const last = page.at(-1);
|
|
4825
|
-
let nextCursor = null;
|
|
4826
|
-
if (more && last !== void 0) {
|
|
4827
|
-
const all = keysOf(last);
|
|
4828
|
-
const keys = [];
|
|
4829
|
-
for (let i = 0; i < keyCount; i += 1) {
|
|
4830
|
-
const value = all[i];
|
|
4831
|
-
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`);
|
|
4832
|
-
keys.push(value);
|
|
4833
|
-
}
|
|
4834
|
-
keys.push(last.rid);
|
|
4835
|
-
nextCursor = encodeCursor(tag, keys);
|
|
4836
|
-
}
|
|
4837
|
-
return {
|
|
4838
|
-
records: page.map((r) => view(decl, r)),
|
|
4839
|
-
nextCursor
|
|
4840
|
-
};
|
|
4841
|
-
},
|
|
4842
|
-
count: async (q) => {
|
|
4843
|
-
reading();
|
|
4844
|
-
const decl = declOf(q.kind);
|
|
4845
|
-
assertWindowAllowed(q.kind, decl, q);
|
|
4846
|
-
const where = planWhere(q.kind, decl, q.where, { allowIn: true });
|
|
4847
|
-
let n = 0;
|
|
4848
|
-
for (const row of table(q.kind).values()) if (inWindow(row, q) && (where === null || where.matches(row.data))) n += 1;
|
|
4849
|
-
return { count: n };
|
|
4850
|
-
},
|
|
4851
|
-
histogram: async (q) => {
|
|
4852
|
-
reading();
|
|
4853
|
-
const decl = declOf(q.kind);
|
|
4854
|
-
assertWindowAllowed(q.kind, decl, {
|
|
4855
|
-
deviceId: q.deviceId,
|
|
4856
|
-
atFrom: q.from
|
|
5026
|
+
} else if (op.op === "patch") {
|
|
5027
|
+
const r = await transport.patch({
|
|
5028
|
+
kind: op.kind,
|
|
5029
|
+
id: op.id,
|
|
5030
|
+
data: op.data,
|
|
5031
|
+
...op.at === void 0 ? {} : { at: op.at },
|
|
5032
|
+
...op.expiresAt === void 0 ? {} : { expiresAt: op.expiresAt },
|
|
5033
|
+
...op.ifRev === void 0 ? {} : { ifRev: op.ifRev }
|
|
4857
5034
|
});
|
|
4858
|
-
|
|
4859
|
-
|
|
4860
|
-
|
|
4861
|
-
|
|
4862
|
-
const step = Math.trunc(q.bucketMs);
|
|
4863
|
-
const counts = /* @__PURE__ */ new Map();
|
|
4864
|
-
for (const row of table(q.kind).values()) {
|
|
4865
|
-
if (q.deviceId !== void 0 && row.deviceId !== q.deviceId) continue;
|
|
4866
|
-
if (row.at === null || row.at < from || row.at >= to) continue;
|
|
4867
|
-
const b = Math.trunc((row.at - from) / step);
|
|
4868
|
-
counts.set(b, (counts.get(b) ?? 0) + 1);
|
|
4869
|
-
}
|
|
4870
|
-
return { buckets: [...counts.entries()].sort(([a], [b]) => a - b).map(([b, count]) => ({
|
|
4871
|
-
bucketStart: from + b * q.bucketMs,
|
|
4872
|
-
count
|
|
4873
|
-
})) };
|
|
4874
|
-
},
|
|
4875
|
-
aggregate: async (q) => {
|
|
4876
|
-
reading();
|
|
4877
|
-
const decl = declOf(q.kind);
|
|
4878
|
-
if (q.op !== "count" && q.field === void 0) throw new InvalidRecordError(`${q.kind}: ${q.op} needs a field`);
|
|
4879
|
-
const extra = [q.field, q.groupBy].filter((f) => f !== void 0);
|
|
4880
|
-
if (extra.length === 0 && q.where === void 0) throw new InvalidRecordError(`${q.kind}: a count with no field and no groupBy is "count"`);
|
|
4881
|
-
const where = planWhere(q.kind, decl, q.where, {
|
|
4882
|
-
allowIn: true,
|
|
4883
|
-
extraFields: extra,
|
|
4884
|
-
groupBy: q.groupBy
|
|
5035
|
+
releasedRefs.push(...r.releasedRefs);
|
|
5036
|
+
results.push({
|
|
5037
|
+
rev: r.rev,
|
|
5038
|
+
deleted: false
|
|
4885
5039
|
});
|
|
4886
|
-
|
|
4887
|
-
const
|
|
4888
|
-
|
|
4889
|
-
|
|
4890
|
-
else {
|
|
4891
|
-
const by = q.groupBy;
|
|
4892
|
-
for (const row of rows) {
|
|
4893
|
-
const g = extractField(row.data, by);
|
|
4894
|
-
groups.set(g, [...groups.get(g) ?? [], row]);
|
|
4895
|
-
}
|
|
4896
|
-
}
|
|
4897
|
-
return { rows: [...groups.entries()].sort(([a], [b]) => compareSql(a, b)).map(([group, members]) => ({
|
|
4898
|
-
group,
|
|
4899
|
-
value: aggregateOf(q.op, q.field, members)
|
|
4900
|
-
})) };
|
|
4901
|
-
},
|
|
4902
|
-
deleteWhere: async (q) => {
|
|
4903
|
-
writing();
|
|
4904
|
-
const decl = declOf(q.kind);
|
|
4905
|
-
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"`);
|
|
4906
|
-
assertWindowAllowed(q.kind, decl, {
|
|
4907
|
-
deviceId: q.deviceId,
|
|
4908
|
-
atFrom: q.atBefore
|
|
5040
|
+
} else {
|
|
5041
|
+
const r = await transport.delete({
|
|
5042
|
+
kind: op.kind,
|
|
5043
|
+
id: op.id
|
|
4909
5044
|
});
|
|
4910
|
-
|
|
4911
|
-
|
|
4912
|
-
|
|
4913
|
-
|
|
4914
|
-
if (q.atBefore !== void 0 && (row.at === null || row.at >= q.atBefore)) return false;
|
|
4915
|
-
return true;
|
|
5045
|
+
secretRefs.push(...r.secretRefs);
|
|
5046
|
+
results.push({
|
|
5047
|
+
rev: null,
|
|
5048
|
+
deleted: r.deleted
|
|
4916
5049
|
});
|
|
4917
|
-
},
|
|
4918
|
-
deleteDevice: async ({ deviceId, kinds }) => {
|
|
4919
|
-
writing();
|
|
4920
|
-
const deleted = {};
|
|
4921
|
-
const secretRefs = [];
|
|
4922
|
-
for (const [kind, decl] of decls) {
|
|
4923
|
-
if (decl.deviceRemoval !== "delete") continue;
|
|
4924
|
-
if (kinds !== void 0 && !kinds.includes(kind)) continue;
|
|
4925
|
-
const result = removeWhere(kind, (row) => row.deviceId === deviceId);
|
|
4926
|
-
deleted[kind] = result.deleted;
|
|
4927
|
-
secretRefs.push(...result.secretRefs);
|
|
4928
|
-
}
|
|
4929
|
-
return {
|
|
4930
|
-
deleted,
|
|
4931
|
-
secretRefs
|
|
4932
|
-
};
|
|
4933
|
-
},
|
|
4934
|
-
allocateId: async ({ kind }) => {
|
|
4935
|
-
writing();
|
|
4936
|
-
declOf(kind);
|
|
4937
|
-
const id = sequences.get(kind) ?? 1;
|
|
4938
|
-
sequences.set(kind, id + 1);
|
|
4939
|
-
pendingAllocated.add(`${kind}:${id}`);
|
|
4940
|
-
return { id };
|
|
4941
5050
|
}
|
|
4942
|
-
}
|
|
5051
|
+
} catch (err) {
|
|
5052
|
+
tables.clear();
|
|
5053
|
+
for (const [name, rows] of before) tables.set(name, rows);
|
|
5054
|
+
nextRid = ridBefore;
|
|
5055
|
+
throw err;
|
|
5056
|
+
}
|
|
5057
|
+
return {
|
|
5058
|
+
results,
|
|
5059
|
+
releasedRefs,
|
|
5060
|
+
secretRefs
|
|
5061
|
+
};
|
|
5062
|
+
},
|
|
5063
|
+
deleteDevice: async ({ deviceId, kinds }) => {
|
|
5064
|
+
writing();
|
|
5065
|
+
const deleted = {};
|
|
5066
|
+
const secretRefs = [];
|
|
5067
|
+
for (const [kind, decl] of decls) {
|
|
5068
|
+
if (decl.deviceRemoval !== "delete") continue;
|
|
5069
|
+
if (kinds !== void 0 && !kinds.includes(kind)) continue;
|
|
5070
|
+
const result = removeWhere(kind, (row) => row.deviceId === deviceId);
|
|
5071
|
+
deleted[kind] = result.deleted;
|
|
5072
|
+
secretRefs.push(...result.secretRefs);
|
|
5073
|
+
}
|
|
5074
|
+
return {
|
|
5075
|
+
deleted,
|
|
5076
|
+
secretRefs
|
|
5077
|
+
};
|
|
5078
|
+
},
|
|
5079
|
+
allocateId: async ({ kind }) => {
|
|
5080
|
+
writing();
|
|
5081
|
+
declOf(kind);
|
|
5082
|
+
const id = sequences.get(kind) ?? 1;
|
|
5083
|
+
sequences.set(kind, id + 1);
|
|
5084
|
+
pendingAllocated.add(`${kind}:${id}`);
|
|
5085
|
+
return { id };
|
|
5086
|
+
}
|
|
5087
|
+
};
|
|
5088
|
+
return {
|
|
5089
|
+
records: createRecordsAccess({
|
|
5090
|
+
owner,
|
|
5091
|
+
transport,
|
|
4943
5092
|
secrets: makeSpecKeychain(owner).access
|
|
4944
5093
|
}),
|
|
4945
5094
|
tables,
|
|
@@ -8028,4 +8177,4 @@ function sleepCancellable(ms, signal) {
|
|
|
8028
8177
|
});
|
|
8029
8178
|
}
|
|
8030
8179
|
//#endregion
|
|
8031
|
-
export { optionalMethod as $,
|
|
8180
|
+
export { optionalMethod as $, PeerBytesTicketSchema as $n, expandAudioChunkToF32le as $r, recordArrayItemPath as $t, HF_REPO as A, RECORD_DELETE_BATCH as An, collectHydratedFieldEntries as Ar, makeProfileBrokerId as At, describeCustomActions as B, REVALIDATE_AFTER_MS as Bn, isSecretMarker as Br, RecordFieldPathSchema as Bt, addonSliceHandleApi as C, asRecordsError as Cn, normalizeNodeId as Cr, ProfileRtspEntrySchema as Ct, createSliceHandle as D, RECORD_CLASSES as Dn, isEvent as Dr, StreamSourceSchema as Dt, createMirrorSource as E, RECORD_BATCH_MAX_BYTES as En, emitReadiness as Er, StreamSourceEntrySchema$1 as Et, DEVICE_CHILDREN_BATCH_MAX as F, RECORD_QUERY_MAX as Fn, resolveHydratedFieldValue as Fr, defineEntryKind as Ft, DEVICE_STATUS_METHOD as G, knownSecretCount as Gn, collectKeychainStoredKeys as Gr, StoredRecordKindDeclarationSchema as Gt, adminUiCapability as H, MIN_SCRUBBED_LENGTH as Hn, makeSecretMarker as Hr, RecordKindDeclarationSchema as Ht, CALLER_STAMPED_CAPABILITIES as I, RECORD_SECRET_COLLECTION_PREFIX as In, SECRET_CLEAR as Ir, entryBody as It, PROVIDER_PIN_FIELD as J, shortSecretRefHash as Jn, isSecretConfigField as Jr, defineRecordKinds as Jt, HISTORY_DEFAULT_MIN_INTERVAL_MS as K, registerKnownSecret as Kn, collectSecretConfigKeys as Kr, assertValidDeclaration as Kt, withoutCallerStamp as L, RECORD_SETTINGS_MAX_ROWS as Ln, classifySecretWrite as Lr, createRecordsAccess as Lt, RawStateResultSchema as M, RECORD_MAX_DATA_BYTES as Mn, dehydrateConfigField as Mr, parseProfileBrokerId as Mt, deviceOpsCapability as N, RECORD_MAX_INDEXES as Nn, dehydrateSchema as Nr, selectAssignedProfileSlots as Nt, DEFAULT_TOKEN_EXPIRY as O, RECORD_DATABASES as On, WELL_KNOWN_TABS as Or, SubscribeAudioChunksInputSchema as Ot, viewerUiCapability as P, RECORD_MAX_INDEX_FIELDS as Pn, hydrateSchema as Pr, makeInMemoryRecords as Pt, method as Q, PEER_BYTES_TICKET_TTL_MS as Qn, audioChunkBytesPerSample as Qr, parseSecretPath as Qt, customAction as R, RECORD_SWEEP_INTERVAL_MS as Rn, isSecretClear as Rr, assertTransactScope as Rt, invokeTrpcLeaf as S, UnknownRecordKindError as Sn, parseSecretRef as Sr, FrameHandleSchema as St, createLazyTrpcSource as T, RECORD_BATCH_MAX as Tn, createEvent as Tr, ProfileSlotStatusSchema as Tt, DEFAULT_RUNTIME_STATE_DURABILITY as U, clearKnownSecrets as Un, toSecretFieldView as Ur, RecordKindNameSchema as Ut, deviceCustomAction as V, createSecretsAccess as Vn, isSecretMarkerLike as Vr, RecordIndexSchema as Vt, DEVICE_SETTINGS_CONTRIBUTION_METHODS as W, forgetKnownSecret as Wn, REDACTED_SECRET as Wr, RecordRetentionSchema as Wt, expandCapMethods as X, PEER_BYTES_MAX_OUTSTANDING as Xn, schemaDeclaresAnyField as Xr, collectSecretLeaves as Xt, event as Y, PEER_BYTES_CHUNK_BYTES as Yn, omitTransientConfig as Yr, REMOVE_LEAF as Yt, isDeviceConfigCap as Z, PEER_BYTES_STALL_MS as Zn, AUDIO_CHUNK_FORMATS as Zr, mapSecretLeaves as Zt, readErrorI18n as _, RecordUniqueViolationError as _n, buildSecretRef as _r, CamProfileSchema as _t, asJsonArray as a, isZodSecret as an, normalizeAddonInitResult as ar, toNodeId as at, isDeviceScopedCap as b, TransactRefusedError as bn, isSecretRef as br, CameraStreamSchema as bt, asString as c, FilterRequiredError as cn, secretTreeFromPaths as cr, ReadinessTimeoutError as ct, parseJsonUnknown as d, NoCallerError as dn, collectSecretMarkerRefs as dr, scopeKey as dt, isAudioChunkFormat as ei, recordSecretCollection as en, DATAPLANE_SECRET_HEADER as er, resolveCapMount as et, hfModelUrl as f, PlaintextSecretError as fn, isSecretRefOwnedBy as fr, AudioChunkFormatSchema as ft, ErrorI18nPayloadSchema as g, RecordTooLargeError as gn, arrayItemFieldPath as gr, CAM_PROFILE_ORDER as gt, ErrorCodeSchema as h, RecordSecretUnavailableError as hn, SECRET_REF_SCHEME as hr, BrokerStatusSchema as ht, asBoolean as i, collectZodSecretPaths as in, classifyStoreError as ir, readNodePin as it, RUNTIME_DEFAULTS as j, RECORD_ID_MAX_LENGTH as jn, collectHydratedFieldValues as jr, makeSourceBrokerId as jt, HF_BASE_URL as k, RECORD_DEFAULT_MAX_DATA_BYTES as kn, WELL_KNOWN_TAB_MAP as kr, SubscribeAudioChunksResultSchema as kt, parseJsonArray as l, ForeignSecretMarkerError as ln, secretTreeFromSchema as lr, emitDownForOwnedCaps as lt, CamstackError as m, RecordNotFoundError as mn, transformSecretWrite as mr, BrokerStatsSchema as mt, sleepCancellable as n, secretArrayPrefixes as nn, DisposerChain as nr, CAP_NODE_PIN_CONTEXT_KEY as nt, asJsonObject as o, BatchTooLargeError as on, mergeSecretStatePaths as or, MODEL_FORMATS as ot, BOOT_RECOVERY_BACKOFF_MS as p, RECORDS_ERROR_CODES as pn, resolveSecretMarkers as pr, AudioStreamPickSchema as pt, HISTORY_UNIT_LABELS as q, scrubKnownSecrets as qn, isKeychainStoredField as qr, declarationsOf as qt, maskUrlCredentials as r, SECRET_META as rn, BaseAddon as rr, nodePin as rt, asNumber as s, DeclarationRefusedError as sn, parseSecretStatePath as sr, ReadinessRegistry as st, sleep as t, recordSecretRef as tn, SHARE_VIEW_KINDS as tr, systemMethod as tt, parseJsonObject as u, InvalidRecordError as un, KeychainWriteRefusedError as ur, readinessKey as ut, userError as v, RecordsError as vn, formatSecretScope as vr, CamStreamKindSchema as vt, createEventBusSliceSource as w, recordsErrorFromMessage as wn, createDurableState as wr, ProfileSlotSchema as wt, createDeviceProxy as x, UnindexedFilterError as xn, normalizeSecretOwner as xr, DecodedAudioChunkSchema as xt, DEVICE_SCOPED_CAPS as y, RevConflictError as yn, globalSecretScope as yr, CamStreamResolutionSchema as yt, defineCustomActions as z, resolveSecretViewsIn as zn, isSecretFieldView as zr, EntryDescriptorSchema as zt };
|