@camstack/system 1.2.448 → 1.2.450

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.
@@ -54,6 +54,34 @@ export interface ControlOps {
54
54
  readonly input: Record<string, never>;
55
55
  readonly output: number;
56
56
  };
57
+ /** Every physical table in the file (storage-admin / records adopt). */
58
+ readonly listPhysicalTables: {
59
+ readonly input: {
60
+ readonly ownerPrefix?: string | undefined;
61
+ };
62
+ readonly output: readonly {
63
+ readonly name: string;
64
+ readonly owner: string | null;
65
+ readonly rows: number;
66
+ readonly bytes: number | null;
67
+ readonly declaredThisBoot: boolean;
68
+ }[];
69
+ };
70
+ /** Paginated `(id, data)` read of a legacy table in this file. */
71
+ readonly readLegacyCollection: {
72
+ readonly input: {
73
+ readonly collection: string;
74
+ readonly cursor?: string | undefined;
75
+ readonly limit?: number | undefined;
76
+ };
77
+ readonly output: {
78
+ readonly rows: readonly {
79
+ readonly id: string;
80
+ readonly data: Record<string, unknown>;
81
+ }[];
82
+ readonly nextCursor: string | null;
83
+ };
84
+ };
57
85
  }
58
86
  export type ControlOp = keyof ControlOps;
59
87
  /** At most this many calls in flight per worker; beyond it a call is refused, never queued. */
@@ -4,7 +4,7 @@ Object.defineProperties(exports, {
4
4
  });
5
5
  require("../../chunk-Cek0wNdY.js");
6
6
  const require_builtins_sqlite_storage_filesystem_storage_addon = require("./filesystem-storage.addon.js");
7
- const require_wal_maintenance = require("../../wal-maintenance-Bj3Z87Dx.js");
7
+ const require_wal_maintenance = require("../../wal-maintenance-6SrioJOn.js");
8
8
  const require_builtins_sqlite_storage_sqlite_settings_addon = require("./sqlite-settings.addon.js");
9
9
  //#region src/builtins/sqlite-storage/config-store.ts
10
10
  var ConfigStore = class {
@@ -1,5 +1,5 @@
1
1
  import { FilesystemStorageAddon, t as FilesystemStorageProvider } from "./filesystem-storage.addon.mjs";
2
- import { A as SQLITE_MMAP_FLOOR_BYTES, B as SqliteOpProfiler, F as SQLITE_ENGINE_STORM_WALL_SHARE, I as SQLITE_PROFILE_REPORT_FLOOR_MS, L as SQLITE_PROFILE_REPORT_INTERVAL_MS, M as SQLITE_PAGE_CACHE_FLOOR_KIB, N as sqliteMmapSizeFor, O as SQLITE_JOURNAL_SIZE_LIMIT_BYTES, P as sqlitePageCacheKibFor, R as SQLITE_PROFILE_TOP_N, V as sqliteEngineStorm, a as WalMaintenance, c as SqliteSettingsBackend, i as WAL_MAINTENANCE_INTERVAL_MS, j as SQLITE_PAGE_CACHE_CEILING_KIB, k as SQLITE_MMAP_CEILING_BYTES, n as WAL_HIGH_WATER_BYTES, r as WAL_IDLE_QUIET_MS, t as WAL_CHECKPOINT_BUSY_TIMEOUT_MS, z as SQLITE_SLOW_CALL_MS } from "../../wal-maintenance-DTmqHKdi.mjs";
2
+ import { A as SQLITE_MMAP_CEILING_BYTES, B as SQLITE_SLOW_CALL_MS, F as sqlitePageCacheKibFor, H as sqliteEngineStorm, I as SQLITE_ENGINE_STORM_WALL_SHARE, L as SQLITE_PROFILE_REPORT_FLOOR_MS, M as SQLITE_PAGE_CACHE_CEILING_KIB, N as SQLITE_PAGE_CACHE_FLOOR_KIB, P as sqliteMmapSizeFor, R as SQLITE_PROFILE_REPORT_INTERVAL_MS, V as SqliteOpProfiler, a as WalMaintenance, i as WAL_MAINTENANCE_INTERVAL_MS, j as SQLITE_MMAP_FLOOR_BYTES, k as SQLITE_JOURNAL_SIZE_LIMIT_BYTES, l as SqliteSettingsBackend, n as WAL_HIGH_WATER_BYTES, r as WAL_IDLE_QUIET_MS, t as WAL_CHECKPOINT_BUSY_TIMEOUT_MS, z as SQLITE_PROFILE_TOP_N } from "../../wal-maintenance-_tiSo8gz.mjs";
3
3
  import { SqliteSettingsAddon } from "./sqlite-settings.addon.mjs";
4
4
  //#region src/builtins/sqlite-storage/config-store.ts
5
5
  var ConfigStore = class {
@@ -35,6 +35,25 @@ export interface OwnedSqliteFile {
35
35
  declaredCollections(): ReadonlySet<string>;
36
36
  /** Does a table of this name exist in this file (declared or not)? */
37
37
  hasTable(name: string): Promise<boolean>;
38
+ /** Physical tables for storage-admin (read-only; may include undeclared legacy). */
39
+ listPhysicalTables(ownerPrefix?: string | undefined): Promise<readonly {
40
+ readonly name: string;
41
+ readonly owner: string | null;
42
+ readonly rows: number;
43
+ readonly bytes: number | null;
44
+ readonly declaredThisBoot: boolean;
45
+ }[]>;
46
+ readLegacyCollection(input: {
47
+ readonly collection: string;
48
+ readonly cursor?: string | undefined;
49
+ readonly limit?: number | undefined;
50
+ }): Promise<{
51
+ readonly rows: readonly {
52
+ readonly id: string;
53
+ readonly data: Record<string, unknown>;
54
+ }[];
55
+ readonly nextCursor: string | null;
56
+ }>;
38
57
  dropRetiredTable(name: string): Promise<DroppedRetiredTable | null>;
39
58
  /** Which thread serves this file: 0 is the engine's main thread. */
40
59
  servingThreadId(): Promise<number>;
@@ -91,6 +110,24 @@ declare abstract class OwnedFileBase implements OwnedSqliteFile {
91
110
  abstract records<K extends RecordsOp>(op: K, input: RecordsInput<K>): Promise<RecordsOutput<K>>;
92
111
  abstract declaredCollections(): ReadonlySet<string>;
93
112
  abstract hasTable(name: string): Promise<boolean>;
113
+ abstract listPhysicalTables(ownerPrefix?: string | undefined): Promise<readonly {
114
+ readonly name: string;
115
+ readonly owner: string | null;
116
+ readonly rows: number;
117
+ readonly bytes: number | null;
118
+ readonly declaredThisBoot: boolean;
119
+ }[]>;
120
+ abstract readLegacyCollection(input: {
121
+ readonly collection: string;
122
+ readonly cursor?: string | undefined;
123
+ readonly limit?: number | undefined;
124
+ }): Promise<{
125
+ readonly rows: readonly {
126
+ readonly id: string;
127
+ readonly data: Record<string, unknown>;
128
+ }[];
129
+ readonly nextCursor: string | null;
130
+ }>;
94
131
  abstract dropRetiredTable(name: string): Promise<DroppedRetiredTable | null>;
95
132
  abstract servingThreadId(): Promise<number>;
96
133
  protected abstract stopConnection(): Promise<void>;
@@ -119,6 +156,24 @@ export declare class InlineOwnedFile extends OwnedFileBase {
119
156
  vector<K extends VectorOp>(op: K, input: VectorInput<K>): Promise<VectorOutput<K>>;
120
157
  declaredCollections(): ReadonlySet<string>;
121
158
  hasTable(name: string): Promise<boolean>;
159
+ listPhysicalTables(ownerPrefix?: string | undefined): Promise<readonly {
160
+ readonly name: string;
161
+ readonly owner: string | null;
162
+ readonly rows: number;
163
+ readonly bytes: number | null;
164
+ readonly declaredThisBoot: boolean;
165
+ }[]>;
166
+ readLegacyCollection(input: {
167
+ readonly collection: string;
168
+ readonly cursor?: string | undefined;
169
+ readonly limit?: number | undefined;
170
+ }): Promise<{
171
+ readonly rows: readonly {
172
+ readonly id: string;
173
+ readonly data: Record<string, unknown>;
174
+ }[];
175
+ readonly nextCursor: string | null;
176
+ }>;
122
177
  dropRetiredTable(name: string): Promise<DroppedRetiredTable | null>;
123
178
  servingThreadId(): Promise<number>;
124
179
  protected stopMaintenance(): void;
@@ -134,6 +189,24 @@ export declare class WorkerOwnedFile extends OwnedFileBase {
134
189
  records<K extends RecordsOp>(op: K, input: RecordsInput<K>): Promise<RecordsOutput<K>>;
135
190
  declaredCollections(): ReadonlySet<string>;
136
191
  hasTable(name: string): Promise<boolean>;
192
+ listPhysicalTables(ownerPrefix?: string | undefined): Promise<readonly {
193
+ readonly name: string;
194
+ readonly owner: string | null;
195
+ readonly rows: number;
196
+ readonly bytes: number | null;
197
+ readonly declaredThisBoot: boolean;
198
+ }[]>;
199
+ readLegacyCollection(input: {
200
+ readonly collection: string;
201
+ readonly cursor?: string | undefined;
202
+ readonly limit?: number | undefined;
203
+ }): Promise<{
204
+ readonly rows: readonly {
205
+ readonly id: string;
206
+ readonly data: Record<string, unknown>;
207
+ }[];
208
+ readonly nextCursor: string | null;
209
+ }>;
137
210
  dropRetiredTable(name: string): Promise<DroppedRetiredTable | null>;
138
211
  servingThreadId(): Promise<number>;
139
212
  protected stopMaintenance(): void;
@@ -23,11 +23,9 @@ import type { SqliteVecVectorIndex } from "./vector-index-vec.js";
23
23
  * of its database that the nightly backup archives in place of the live files
24
24
  * (D693).
25
25
  *
26
- * It ALSO serves `vector-store` (singleton, internal), from the settings file's
27
- * open handle. That capability first shipped as its own addon and the
28
- * separation cost two round trips per write — caller → door → engine — plus a
29
- * runner process, to reach a database this addon already has open. The
30
- * capability is what keeps the backend swappable; the package never was.
26
+ * It ALSO serves `vector-store` (singleton, internal), from the **events**
27
+ * file's worker thread (sqlite-vec loaded there). The capability is what keeps
28
+ * the backend swappable; the package never was.
31
29
  */
32
30
  export declare class SqliteSettingsAddon extends BaseAddon {
33
31
  private settingsFile;
@@ -62,7 +60,7 @@ export declare class SqliteSettingsAddon extends BaseAddon {
62
60
  getBackend(): SqliteSettingsBackend | null;
63
61
  /** The placement router; null before `onInitialize`. */
64
62
  getRouter(): PlacementRouter | null;
65
- /** Exposed for tests; null before `onInitialize`. */
63
+ /** Exposed for tests; vectors are served from the events file (P5). */
66
64
  getVectorIndex(): SqliteVecVectorIndex | null;
67
65
  }
68
66
  export default SqliteSettingsAddon;
@@ -5,7 +5,7 @@ Object.defineProperties(exports, {
5
5
  const require_chunk = require("../../chunk-Cek0wNdY.js");
6
6
  const require_dist = require("../../dist-Ct88catN.js");
7
7
  const require_retired_settings_keys = require("../../retired-settings-keys-D_VwZiDt.js");
8
- const require_wal_maintenance = require("../../wal-maintenance-Bj3Z87Dx.js");
8
+ const require_wal_maintenance = require("../../wal-maintenance-6SrioJOn.js");
9
9
  const require_sqlite_snapshot_protocol = require("../../sqlite-snapshot-protocol-B9OndqZv.js");
10
10
  const require_wal_checkpoint_policy = require("../../wal-checkpoint-policy-d2z2qPqx.js");
11
11
  let node_fs_promises = require("node:fs/promises");
@@ -934,6 +934,12 @@ var InlineOwnedFile = class extends OwnedFileBase {
934
934
  async hasTable(name) {
935
935
  return require_wal_maintenance.callControl(require_wal_maintenance.controlTargetOf(this.backend, 0), "hasTable", { name });
936
936
  }
937
+ listPhysicalTables(ownerPrefix) {
938
+ return Promise.resolve(require_wal_maintenance.callControl(require_wal_maintenance.controlTargetOf(this.backend, 0), "listPhysicalTables", { ownerPrefix }));
939
+ }
940
+ readLegacyCollection(input) {
941
+ return Promise.resolve(require_wal_maintenance.callControl(require_wal_maintenance.controlTargetOf(this.backend, 0), "readLegacyCollection", input));
942
+ }
937
943
  async dropRetiredTable(name) {
938
944
  return require_wal_maintenance.callControl(require_wal_maintenance.controlTargetOf(this.backend, 0), "dropRetiredTable", { name });
939
945
  }
@@ -988,6 +994,12 @@ var WorkerOwnedFile = class extends OwnedFileBase {
988
994
  hasTable(name) {
989
995
  return this.client.control("hasTable", { name });
990
996
  }
997
+ listPhysicalTables(ownerPrefix) {
998
+ return this.client.control("listPhysicalTables", { ownerPrefix });
999
+ }
1000
+ readLegacyCollection(input) {
1001
+ return this.client.control("readLegacyCollection", input);
1002
+ }
991
1003
  dropRetiredTable(name) {
992
1004
  return this.client.control("dropRetiredTable", { name });
993
1005
  }
@@ -1608,11 +1620,13 @@ var StorageAdminProvider = class {
1608
1620
  logger;
1609
1621
  installedOwners;
1610
1622
  records;
1611
- constructor(backend, logger, installedOwners, records) {
1623
+ peerFiles;
1624
+ constructor(backend, logger, installedOwners, records, peerFiles = async () => []) {
1612
1625
  this.backend = backend;
1613
1626
  this.logger = logger;
1614
1627
  this.installedOwners = installedOwners;
1615
1628
  this.records = records;
1629
+ this.peerFiles = peerFiles;
1616
1630
  }
1617
1631
  listKinds(input) {
1618
1632
  return this.records.listKinds(input);
@@ -1626,8 +1640,25 @@ var StorageAdminProvider = class {
1626
1640
  isAdoptedLegacyTable(input) {
1627
1641
  return this.records.isAdoptedLegacyTable(input.collection).then((adopted) => ({ adopted }));
1628
1642
  }
1629
- readLegacyCollection(input) {
1630
- return Promise.resolve(this.backend.readLegacyCollection(input));
1643
+ async readLegacyCollection(input) {
1644
+ if (this.backend.hasTable(input.collection)) {
1645
+ const page = this.backend.readLegacyCollection(input);
1646
+ return {
1647
+ rows: [...page.rows],
1648
+ nextCursor: page.nextCursor
1649
+ };
1650
+ }
1651
+ for (const file of await this.peerFiles()) if (await file.hasTable(input.collection)) {
1652
+ const page = await file.readLegacyCollection(input);
1653
+ return {
1654
+ rows: [...page.rows],
1655
+ nextCursor: page.nextCursor
1656
+ };
1657
+ }
1658
+ return {
1659
+ rows: [],
1660
+ nextCursor: null
1661
+ };
1631
1662
  }
1632
1663
  /** May this table be dropped AT ALL? Throws with the reason when not. */
1633
1664
  async assertDroppable(collection) {
@@ -1643,12 +1674,14 @@ var StorageAdminProvider = class {
1643
1674
  if (installed.has(owner) && !await this.records.isAdoptedLegacyTable(collection)) throw new Error(`drop refused: "${collection}" belongs to the installed addon "${owner}"`);
1644
1675
  }
1645
1676
  async listTables(input) {
1646
- const tables = this.backend.listTables(input.ownerPrefix);
1677
+ const tables = [...this.backend.listTables(input.ownerPrefix)];
1678
+ for (const file of await this.peerFiles()) tables.push(...await file.listPhysicalTables(input.ownerPrefix));
1679
+ tables.sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0);
1647
1680
  this.logger.info("storage-admin: listed tables", { meta: {
1648
1681
  tables: tables.length,
1649
1682
  ownerPrefix: input.ownerPrefix ?? null
1650
1683
  } });
1651
- return { tables: [...tables] };
1684
+ return { tables };
1652
1685
  }
1653
1686
  async dropCollection(input) {
1654
1687
  try {
@@ -1812,11 +1845,9 @@ var DATABASE_FILE_NAMES = {
1812
1845
  * of its database that the nightly backup archives in place of the live files
1813
1846
  * (D693).
1814
1847
  *
1815
- * It ALSO serves `vector-store` (singleton, internal), from the settings file's
1816
- * open handle. That capability first shipped as its own addon and the
1817
- * separation cost two round trips per write — caller → door → engine — plus a
1818
- * runner process, to reach a database this addon already has open. The
1819
- * capability is what keeps the backend swappable; the package never was.
1848
+ * It ALSO serves `vector-store` (singleton, internal), from the **events**
1849
+ * file's worker thread (sqlite-vec loaded there). The capability is what keeps
1850
+ * the backend swappable; the package never was.
1820
1851
  */
1821
1852
  var SqliteSettingsAddon = class extends require_dist.BaseAddon {
1822
1853
  settingsFile = null;
@@ -1864,7 +1895,7 @@ var SqliteSettingsAddon = class extends require_dist.BaseAddon {
1864
1895
  livePath: settingsPath,
1865
1896
  thread: "main",
1866
1897
  autoVacuum: "none",
1867
- loadVectorExtension: true
1898
+ loadVectorExtension: false
1868
1899
  }, deps);
1869
1900
  if (!(settings instanceof InlineOwnedFile)) throw new Error("sqlite-settings: the settings file must be served on the main thread");
1870
1901
  this.settingsFile = settings;
@@ -1877,8 +1908,7 @@ var SqliteSettingsAddon = class extends require_dist.BaseAddon {
1877
1908
  logger: this.ctx.logger.child("Placement")
1878
1909
  });
1879
1910
  this.router = router;
1880
- const vectorIndex = settings.getVectorIndex();
1881
- if (vectorIndex === null) throw new Error("vector-store: the settings file has no vector index");
1911
+ const vectorProvider = require_wal_maintenance.vectorProviderOfOwnedFile(() => router.recordsFileFor("events"));
1882
1912
  const records = new RecordsProvider(router, this.ctx.logger.child("Records"));
1883
1913
  await records.init();
1884
1914
  this.startRecordsSweep(records);
@@ -1894,7 +1924,7 @@ var SqliteSettingsAddon = class extends require_dist.BaseAddon {
1894
1924
  },
1895
1925
  {
1896
1926
  capability: require_dist.vectorStoreCapability,
1897
- provider: require_wal_maintenance.vectorProviderOf(vectorIndex)
1927
+ provider: vectorProvider
1898
1928
  },
1899
1929
  {
1900
1930
  capability: require_dist.databaseSnapshotCapability,
@@ -1902,7 +1932,7 @@ var SqliteSettingsAddon = class extends require_dist.BaseAddon {
1902
1932
  },
1903
1933
  {
1904
1934
  capability: require_dist.storageAdminCapability,
1905
- provider: new StorageAdminProvider(settings.backend, this.ctx.logger.child("StorageAdmin"), async () => new Set((await this.ctx.api.addons.list.query()).map((addon) => addon.manifest.id)), records)
1935
+ provider: new StorageAdminProvider(settings.backend, this.ctx.logger.child("StorageAdmin"), async () => new Set((await this.ctx.api.addons.list.query()).map((addon) => addon.manifest.id)), records, async () => router.openFiles().filter((file) => file.databaseId !== "settings"))
1906
1936
  }
1907
1937
  ];
1908
1938
  }
@@ -1963,19 +1993,19 @@ var SqliteSettingsAddon = class extends require_dist.BaseAddon {
1963
1993
  getRouter() {
1964
1994
  return this.router;
1965
1995
  }
1966
- /** Exposed for tests; null before `onInitialize`. */
1996
+ /** Exposed for tests; vectors are served from the events file (P5). */
1967
1997
  getVectorIndex() {
1968
- return this.settingsFile?.getVectorIndex() ?? null;
1998
+ return null;
1969
1999
  }
1970
2000
  };
1971
- /** How a non-settings file is opened: its own worker; `events` is the one that holds vectors later. */
2001
+ /** How a non-settings file is opened: its own worker; `events` loads sqlite-vec. */
1972
2002
  function workerSpec(databaseId, livePath) {
1973
2003
  return {
1974
2004
  databaseId,
1975
2005
  livePath,
1976
2006
  thread: "worker",
1977
2007
  autoVacuum: "incremental",
1978
- loadVectorExtension: false
2008
+ loadVectorExtension: databaseId === "events"
1979
2009
  };
1980
2010
  }
1981
2011
  //#endregion
@@ -1,6 +1,6 @@
1
1
  import { $ as STORAGE_ADMIN_SCOPED_BASES, $i as parseSettingsArrayAdoptsFrom, $r as NoCallerError, Gn as recordsCapability, Hr as BaseAddon, It as dataStoreProviderCapability, Jr as DeclarationRefusedError, Lt as databaseSnapshotCapability, Q as STORAGE_ADMIN_MOVED_COLLECTIONS, S as DATA_STORE_DATABASES, Vr as errMsg, Yi as normalizeSecretOwner, _i as UnknownRecordKindError, _t as bareAddonId, b as DATABASE_SNAPSHOT_SUFFIX, dr as storageAdminCapability, ea as parseSettingsBrokersAdoptsFrom, ii as RECORD_SWEEP_INTERVAL_MS, si as RUNTIME_DEFAULTS, ui as RecordKindDeclarationSchema, wr as vectorStoreCapability, x as DATABASE_SNAPSHOT_TIMEOUT_MS, y as DATABASE_SNAPSHOT_PARTIAL_SUFFIX } from "../../dist-DV2ll9Hi.mjs";
2
2
  import { i as retiredKeyStoreOf, n as purgeRetiredSettingsKeys } from "../../retired-settings-keys-Bhwe4ymb.mjs";
3
- import { C as callControl, D as controlTargetOf, E as callVector, S as RecordsEngine, T as callRecords, _ as isFileHostMessage, a as WalMaintenance, c as SqliteSettingsBackend, d as DatabaseBusyError, f as DuplicatePlacementError, g as collectTransferables, l as CollectionPlacementError, o as createVectorIndex, p as rehydrateError, s as vectorProviderOf, u as CrossDatabaseTransactError, w as callData, x as trustResult } from "../../wal-maintenance-DTmqHKdi.mjs";
3
+ import { C as RecordsEngine, D as callVector, E as callRecords, O as controlTargetOf, S as trustResult, T as callData, _ as collectTransferables, a as WalMaintenance, c as vectorProviderOfOwnedFile, d as CrossDatabaseTransactError, f as DatabaseBusyError, l as SqliteSettingsBackend, m as rehydrateError, o as createVectorIndex, p as DuplicatePlacementError, s as vectorProviderOf, u as CollectionPlacementError, v as isFileHostMessage, w as callControl } from "../../wal-maintenance-_tiSo8gz.mjs";
4
4
  import { r as isSnapshotWorkerMessage } from "../../sqlite-snapshot-protocol-2QaTouWV.mjs";
5
5
  import { a as isWorkerMessage, t as WAL_CHECKPOINT_LARGE_PASS_FRAMES } from "../../wal-checkpoint-policy-BahrTtyD.mjs";
6
6
  import { createRequire } from "node:module";
@@ -928,6 +928,12 @@ var InlineOwnedFile = class extends OwnedFileBase {
928
928
  async hasTable(name) {
929
929
  return callControl(controlTargetOf(this.backend, 0), "hasTable", { name });
930
930
  }
931
+ listPhysicalTables(ownerPrefix) {
932
+ return Promise.resolve(callControl(controlTargetOf(this.backend, 0), "listPhysicalTables", { ownerPrefix }));
933
+ }
934
+ readLegacyCollection(input) {
935
+ return Promise.resolve(callControl(controlTargetOf(this.backend, 0), "readLegacyCollection", input));
936
+ }
931
937
  async dropRetiredTable(name) {
932
938
  return callControl(controlTargetOf(this.backend, 0), "dropRetiredTable", { name });
933
939
  }
@@ -982,6 +988,12 @@ var WorkerOwnedFile = class extends OwnedFileBase {
982
988
  hasTable(name) {
983
989
  return this.client.control("hasTable", { name });
984
990
  }
991
+ listPhysicalTables(ownerPrefix) {
992
+ return this.client.control("listPhysicalTables", { ownerPrefix });
993
+ }
994
+ readLegacyCollection(input) {
995
+ return this.client.control("readLegacyCollection", input);
996
+ }
985
997
  dropRetiredTable(name) {
986
998
  return this.client.control("dropRetiredTable", { name });
987
999
  }
@@ -1602,11 +1614,13 @@ var StorageAdminProvider = class {
1602
1614
  logger;
1603
1615
  installedOwners;
1604
1616
  records;
1605
- constructor(backend, logger, installedOwners, records) {
1617
+ peerFiles;
1618
+ constructor(backend, logger, installedOwners, records, peerFiles = async () => []) {
1606
1619
  this.backend = backend;
1607
1620
  this.logger = logger;
1608
1621
  this.installedOwners = installedOwners;
1609
1622
  this.records = records;
1623
+ this.peerFiles = peerFiles;
1610
1624
  }
1611
1625
  listKinds(input) {
1612
1626
  return this.records.listKinds(input);
@@ -1620,8 +1634,25 @@ var StorageAdminProvider = class {
1620
1634
  isAdoptedLegacyTable(input) {
1621
1635
  return this.records.isAdoptedLegacyTable(input.collection).then((adopted) => ({ adopted }));
1622
1636
  }
1623
- readLegacyCollection(input) {
1624
- return Promise.resolve(this.backend.readLegacyCollection(input));
1637
+ async readLegacyCollection(input) {
1638
+ if (this.backend.hasTable(input.collection)) {
1639
+ const page = this.backend.readLegacyCollection(input);
1640
+ return {
1641
+ rows: [...page.rows],
1642
+ nextCursor: page.nextCursor
1643
+ };
1644
+ }
1645
+ for (const file of await this.peerFiles()) if (await file.hasTable(input.collection)) {
1646
+ const page = await file.readLegacyCollection(input);
1647
+ return {
1648
+ rows: [...page.rows],
1649
+ nextCursor: page.nextCursor
1650
+ };
1651
+ }
1652
+ return {
1653
+ rows: [],
1654
+ nextCursor: null
1655
+ };
1625
1656
  }
1626
1657
  /** May this table be dropped AT ALL? Throws with the reason when not. */
1627
1658
  async assertDroppable(collection) {
@@ -1637,12 +1668,14 @@ var StorageAdminProvider = class {
1637
1668
  if (installed.has(owner) && !await this.records.isAdoptedLegacyTable(collection)) throw new Error(`drop refused: "${collection}" belongs to the installed addon "${owner}"`);
1638
1669
  }
1639
1670
  async listTables(input) {
1640
- const tables = this.backend.listTables(input.ownerPrefix);
1671
+ const tables = [...this.backend.listTables(input.ownerPrefix)];
1672
+ for (const file of await this.peerFiles()) tables.push(...await file.listPhysicalTables(input.ownerPrefix));
1673
+ tables.sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0);
1641
1674
  this.logger.info("storage-admin: listed tables", { meta: {
1642
1675
  tables: tables.length,
1643
1676
  ownerPrefix: input.ownerPrefix ?? null
1644
1677
  } });
1645
- return { tables: [...tables] };
1678
+ return { tables };
1646
1679
  }
1647
1680
  async dropCollection(input) {
1648
1681
  try {
@@ -1806,11 +1839,9 @@ var DATABASE_FILE_NAMES = {
1806
1839
  * of its database that the nightly backup archives in place of the live files
1807
1840
  * (D693).
1808
1841
  *
1809
- * It ALSO serves `vector-store` (singleton, internal), from the settings file's
1810
- * open handle. That capability first shipped as its own addon and the
1811
- * separation cost two round trips per write — caller → door → engine — plus a
1812
- * runner process, to reach a database this addon already has open. The
1813
- * capability is what keeps the backend swappable; the package never was.
1842
+ * It ALSO serves `vector-store` (singleton, internal), from the **events**
1843
+ * file's worker thread (sqlite-vec loaded there). The capability is what keeps
1844
+ * the backend swappable; the package never was.
1814
1845
  */
1815
1846
  var SqliteSettingsAddon = class extends BaseAddon {
1816
1847
  settingsFile = null;
@@ -1858,7 +1889,7 @@ var SqliteSettingsAddon = class extends BaseAddon {
1858
1889
  livePath: settingsPath,
1859
1890
  thread: "main",
1860
1891
  autoVacuum: "none",
1861
- loadVectorExtension: true
1892
+ loadVectorExtension: false
1862
1893
  }, deps);
1863
1894
  if (!(settings instanceof InlineOwnedFile)) throw new Error("sqlite-settings: the settings file must be served on the main thread");
1864
1895
  this.settingsFile = settings;
@@ -1871,8 +1902,7 @@ var SqliteSettingsAddon = class extends BaseAddon {
1871
1902
  logger: this.ctx.logger.child("Placement")
1872
1903
  });
1873
1904
  this.router = router;
1874
- const vectorIndex = settings.getVectorIndex();
1875
- if (vectorIndex === null) throw new Error("vector-store: the settings file has no vector index");
1905
+ const vectorProvider = vectorProviderOfOwnedFile(() => router.recordsFileFor("events"));
1876
1906
  const records = new RecordsProvider(router, this.ctx.logger.child("Records"));
1877
1907
  await records.init();
1878
1908
  this.startRecordsSweep(records);
@@ -1888,7 +1918,7 @@ var SqliteSettingsAddon = class extends BaseAddon {
1888
1918
  },
1889
1919
  {
1890
1920
  capability: vectorStoreCapability,
1891
- provider: vectorProviderOf(vectorIndex)
1921
+ provider: vectorProvider
1892
1922
  },
1893
1923
  {
1894
1924
  capability: databaseSnapshotCapability,
@@ -1896,7 +1926,7 @@ var SqliteSettingsAddon = class extends BaseAddon {
1896
1926
  },
1897
1927
  {
1898
1928
  capability: storageAdminCapability,
1899
- provider: new StorageAdminProvider(settings.backend, this.ctx.logger.child("StorageAdmin"), async () => new Set((await this.ctx.api.addons.list.query()).map((addon) => addon.manifest.id)), records)
1929
+ provider: new StorageAdminProvider(settings.backend, this.ctx.logger.child("StorageAdmin"), async () => new Set((await this.ctx.api.addons.list.query()).map((addon) => addon.manifest.id)), records, async () => router.openFiles().filter((file) => file.databaseId !== "settings"))
1900
1930
  }
1901
1931
  ];
1902
1932
  }
@@ -1957,19 +1987,19 @@ var SqliteSettingsAddon = class extends BaseAddon {
1957
1987
  getRouter() {
1958
1988
  return this.router;
1959
1989
  }
1960
- /** Exposed for tests; null before `onInitialize`. */
1990
+ /** Exposed for tests; vectors are served from the events file (P5). */
1961
1991
  getVectorIndex() {
1962
- return this.settingsFile?.getVectorIndex() ?? null;
1992
+ return null;
1963
1993
  }
1964
1994
  };
1965
- /** How a non-settings file is opened: its own worker; `events` is the one that holds vectors later. */
1995
+ /** How a non-settings file is opened: its own worker; `events` loads sqlite-vec. */
1966
1996
  function workerSpec(databaseId, livePath) {
1967
1997
  return {
1968
1998
  databaseId,
1969
1999
  livePath,
1970
2000
  thread: "worker",
1971
2001
  autoVacuum: "incremental",
1972
- loadVectorExtension: false
2002
+ loadVectorExtension: databaseId === "events"
1973
2003
  };
1974
2004
  }
1975
2005
  //#endregion
@@ -8,6 +8,7 @@
8
8
  */
9
9
  import { type IScopedLogger, type IStorageAdminProvider, type StorageTable } from "@camstack/types";
10
10
  import type { RecordsProvider } from "./records/records-provider.js";
11
+ import type { OwnedSqliteFile } from "./owned-sqlite-file.js";
11
12
  import type { SqliteSettingsBackend } from "./sqlite-settings-backend.js";
12
13
  export declare class StorageAdminProvider implements IStorageAdminProvider {
13
14
  private readonly backend;
@@ -16,7 +17,9 @@ export declare class StorageAdminProvider implements IStorageAdminProvider {
16
17
  private readonly installedOwners;
17
18
  /** The records provider the System -> Data and migration methods delegate to (D881). */
18
19
  private readonly records;
19
- constructor(backend: SqliteSettingsBackend, logger: IScopedLogger, installedOwners: () => Promise<ReadonlySet<string>>, records: Pick<RecordsProvider, "listKinds" | "readRecords" | "adoptRecords" | "isAdoptedLegacyTable">);
20
+ /** Non-settings files (`events.db`, `history.db`) for legacy table listing and reads. */
21
+ private readonly peerFiles;
22
+ constructor(backend: SqliteSettingsBackend, logger: IScopedLogger, installedOwners: () => Promise<ReadonlySet<string>>, records: Pick<RecordsProvider, "listKinds" | "readRecords" | "adoptRecords" | "isAdoptedLegacyTable">, peerFiles?: () => Promise<readonly OwnedSqliteFile[]>);
20
23
  listKinds(input: Parameters<IStorageAdminProvider["listKinds"]>[0]): ReturnType<IStorageAdminProvider["listKinds"]>;
21
24
  readRecords(input: Parameters<IStorageAdminProvider["readRecords"]>[0]): ReturnType<IStorageAdminProvider["readRecords"]>;
22
25
  adoptRecords(input: Parameters<IStorageAdminProvider["adoptRecords"]>[0]): ReturnType<IStorageAdminProvider["adoptRecords"]>;
@@ -1,4 +1,5 @@
1
1
  import type { IScopedLogger, IVectorStoreProvider } from "@camstack/types";
2
+ import type { OwnedSqliteFile } from "./owned-sqlite-file.js";
2
3
  import type { SqliteSettingsBackend } from "./sqlite-settings-backend.js";
3
4
  import { SqliteVecVectorIndex } from "./vector-index-vec.js";
4
5
  /**
@@ -17,6 +18,11 @@ import { SqliteVecVectorIndex } from "./vector-index-vec.js";
17
18
  */
18
19
  export declare function createVectorIndex(backend: SqliteSettingsBackend, logger: IScopedLogger): SqliteVecVectorIndex;
19
20
  /**
21
+ * `vector-store` served from the events worker (P5): every call opens or reuses
22
+ * `events.db` with sqlite-vec loaded there, not on the settings thread.
23
+ */
24
+ export declare function vectorProviderOfOwnedFile(openEvents: () => Promise<OwnedSqliteFile>): IVectorStoreProvider;
25
+ /**
20
26
  * The `vector-store` provider surface over one sqlite-vec index. Extracted
21
27
  * from the addon so the main thread (settings) and the file-host worker
22
28
  * (events) serve the SAME mapping.
@@ -1,5 +1,5 @@
1
1
  require("./chunk-Cek0wNdY.js");
2
- const require_wal_maintenance = require("./wal-maintenance-Bj3Z87Dx.js");
2
+ const require_wal_maintenance = require("./wal-maintenance-6SrioJOn.js");
3
3
  let node_worker_threads = require("node:worker_threads");
4
4
  //#region src/builtins/sqlite-storage/file-host-worker.ts
5
5
  /**
@@ -1,4 +1,4 @@
1
- import { C as callControl, D as controlTargetOf, E as callVector, S as RecordsEngine, T as callRecords, a as WalMaintenance, b as trustInput, c as SqliteSettingsBackend, g as collectTransferables, m as serializeError, o as createVectorIndex, s as vectorProviderOf, v as isFileHostRequest, w as callData, y as isFileHostWorkerData } from "./wal-maintenance-DTmqHKdi.mjs";
1
+ import { C as RecordsEngine, D as callVector, E as callRecords, O as controlTargetOf, T as callData, _ as collectTransferables, a as WalMaintenance, b as isFileHostWorkerData, h as serializeError, l as SqliteSettingsBackend, o as createVectorIndex, s as vectorProviderOf, w as callControl, x as trustInput, y as isFileHostRequest } from "./wal-maintenance-_tiSo8gz.mjs";
2
2
  import { parentPort, threadId, workerData } from "node:worker_threads";
3
3
  //#region src/builtins/sqlite-storage/file-host-worker.ts
4
4
  /**
package/dist/index.js CHANGED
@@ -27,7 +27,7 @@ const require_builtins_loki_logging_index = require("./builtins/loki-logging/ind
27
27
  const require_builtins_native_metrics_native_metrics_addon = require("./builtins/native-metrics/native-metrics.addon.js");
28
28
  const require_builtins_device_history_device_history_addon = require("./builtins/device-history/device-history.addon.js");
29
29
  const require_builtins_sqlite_storage_filesystem_storage_addon = require("./builtins/sqlite-storage/filesystem-storage.addon.js");
30
- const require_wal_maintenance = require("./wal-maintenance-Bj3Z87Dx.js");
30
+ const require_wal_maintenance = require("./wal-maintenance-6SrioJOn.js");
31
31
  const require_builtins_sqlite_storage_sqlite_settings_addon = require("./builtins/sqlite-storage/sqlite-settings.addon.js");
32
32
  const require_builtins_sqlite_storage_index = require("./builtins/sqlite-storage/index.js");
33
33
  const require_builtins_storage_orchestrator_storage_orchestrator_addon = require("./builtins/storage-orchestrator/storage-orchestrator.addon.js");
package/dist/index.mjs CHANGED
@@ -26,7 +26,7 @@ import { LokiDestination, LokiLoggingAddon } from "./builtins/loki-logging/index
26
26
  import NativeMetricsAddon, { a as NativeMetricsProvider, n as nodeProcReader, r as parseProcStat } from "./builtins/native-metrics/native-metrics.addon.mjs";
27
27
  import { DeviceHistoryAddon } from "./builtins/device-history/device-history.addon.mjs";
28
28
  import { FilesystemStorageAddon, t as FilesystemStorageProvider } from "./builtins/sqlite-storage/filesystem-storage.addon.mjs";
29
- import { c as SqliteSettingsBackend } from "./wal-maintenance-DTmqHKdi.mjs";
29
+ import { l as SqliteSettingsBackend } from "./wal-maintenance-_tiSo8gz.mjs";
30
30
  import { SqliteSettingsAddon } from "./builtins/sqlite-storage/sqlite-settings.addon.mjs";
31
31
  import { ConfigStore, DeviceStore } from "./builtins/sqlite-storage/index.mjs";
32
32
  import { StorageOrchestratorAddon, a as stripForwardedCaller, i as createHubCapForwardService, l as STORAGE_DRAIN_STATE_LEGACY, n as HUB_CAP_FWD_ACTION, o as buildStorageLocationRegistry, r as HUB_CAP_FWD_SERVICE, t as StorageOrchestratorService, u as storageOrchestratorRecordKinds } from "./builtins/storage-orchestrator/storage-orchestrator.addon.mjs";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/system",
3
- "version": "1.2.448",
3
+ "version": "1.2.450",
4
4
  "description": "Core addon for CamStack — builtins, pipeline, process management, auth, logging, events",
5
5
  "keywords": [
6
6
  "camstack",