@noy-db/in-devtools 0.2.0-pre.6
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/LICENSE +21 -0
- package/dist/index.cjs +99 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +64 -0
- package/dist/index.d.ts +64 -0
- package/dist/index.js +72 -0
- package/dist/index.js.map +1 -0
- package/package.json +38 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 vLannaAi
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
createInspector: () => createInspector
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(index_exports);
|
|
26
|
+
|
|
27
|
+
// src/snapshot.ts
|
|
28
|
+
async function listVaults(noydb) {
|
|
29
|
+
return noydb.listAccessibleVaults();
|
|
30
|
+
}
|
|
31
|
+
async function snapshot(vault) {
|
|
32
|
+
const dump = await vault.dumpSchema({ withStats: true });
|
|
33
|
+
const collections = Object.entries(dump.collections).map(([name, desc]) => ({
|
|
34
|
+
name,
|
|
35
|
+
fields: desc.fields,
|
|
36
|
+
indexes: desc.indexes,
|
|
37
|
+
refs: desc.refs,
|
|
38
|
+
...desc.stats !== void 0 ? { stats: desc.stats } : {}
|
|
39
|
+
}));
|
|
40
|
+
return { vault: dump.vault, collections };
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// src/records.ts
|
|
44
|
+
var DEFAULT_LIMIT = 50;
|
|
45
|
+
var MAX_LIMIT = 500;
|
|
46
|
+
function clampLimit(n) {
|
|
47
|
+
if (n === void 0 || Number.isNaN(n)) return DEFAULT_LIMIT;
|
|
48
|
+
return Math.max(1, Math.min(MAX_LIMIT, Math.floor(n)));
|
|
49
|
+
}
|
|
50
|
+
function clampOffset(n) {
|
|
51
|
+
if (n === void 0 || Number.isNaN(n) || n < 0) return 0;
|
|
52
|
+
return Math.floor(n);
|
|
53
|
+
}
|
|
54
|
+
async function records(vault, collection, opts = {}) {
|
|
55
|
+
const limit = clampLimit(opts.limit);
|
|
56
|
+
const offset = clampOffset(opts.offset);
|
|
57
|
+
const all = await vault.collection(collection).list();
|
|
58
|
+
return {
|
|
59
|
+
rows: all.slice(offset, offset + limit),
|
|
60
|
+
total: all.length,
|
|
61
|
+
limit,
|
|
62
|
+
offset
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// src/events.ts
|
|
67
|
+
function subscribe(noydb, handler) {
|
|
68
|
+
return noydb.onAfterWrite(handler);
|
|
69
|
+
}
|
|
70
|
+
function pendingWrites(noydb) {
|
|
71
|
+
const q = noydb.writeQueue;
|
|
72
|
+
return { pending: q.pending, depth: q.depth };
|
|
73
|
+
}
|
|
74
|
+
function subscribeConflicts(noydb, handler) {
|
|
75
|
+
return noydb.onWriteConflict(handler);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// src/meter.ts
|
|
79
|
+
function meterSnapshot(meter) {
|
|
80
|
+
return meter ? meter.snapshot() : null;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// src/index.ts
|
|
84
|
+
function createInspector(noydb, opts) {
|
|
85
|
+
return {
|
|
86
|
+
listVaults: () => listVaults(noydb),
|
|
87
|
+
snapshot: (vault) => snapshot(vault),
|
|
88
|
+
records: (vault, collection, opts2) => records(vault, collection, opts2),
|
|
89
|
+
subscribe: (handler) => subscribe(noydb, handler),
|
|
90
|
+
subscribeConflicts: (handler) => subscribeConflicts(noydb, handler),
|
|
91
|
+
pendingWrites: () => pendingWrites(noydb),
|
|
92
|
+
meterSnapshot: () => meterSnapshot(opts?.meter)
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
96
|
+
0 && (module.exports = {
|
|
97
|
+
createInspector
|
|
98
|
+
});
|
|
99
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/snapshot.ts","../src/records.ts","../src/events.ts","../src/meter.ts"],"sourcesContent":["import type { Vault } from '@noy-db/hub'\nimport type { Inspector, InspectorNoydb, InspectorMeter } from './types.js'\nimport { listVaults, snapshot } from './snapshot.js'\nimport { records } from './records.js'\nimport { subscribe, subscribeConflicts, pendingWrites } from './events.js'\nimport { meterSnapshot } from './meter.js'\n\nexport function createInspector(noydb: InspectorNoydb, opts?: { meter?: InspectorMeter }): Inspector {\n return {\n listVaults: () => listVaults(noydb),\n snapshot: (vault: Vault) => snapshot(vault),\n records: (vault, collection, opts) => records(vault, collection, opts),\n subscribe: (handler) => subscribe(noydb, handler),\n subscribeConflicts: (handler) => subscribeConflicts(noydb, handler),\n pendingWrites: () => pendingWrites(noydb),\n meterSnapshot: () => meterSnapshot(opts?.meter),\n }\n}\n\nexport type {\n Inspector,\n VaultInfo,\n InspectorSnapshot,\n InspectorCollection,\n RecordPage,\n InspectorWriteEvent,\n InspectorWriteConflict,\n PendingWrites,\n InspectorMeter,\n} from './types.js'\n","import type { Vault } from '@noy-db/hub'\nimport type { InspectorSnapshot, InspectorCollection, VaultInfo, InspectorNoydb } from './types.js'\n\nexport async function listVaults(noydb: InspectorNoydb): Promise<ReadonlyArray<VaultInfo>> {\n return noydb.listAccessibleVaults()\n}\n\nexport async function snapshot(vault: Vault): Promise<InspectorSnapshot> {\n // withStats populates per-collection record/byte stats; opaque to the store.\n const dump = await vault.dumpSchema({ withStats: true })\n // Omit `stats` when absent rather than setting it to `undefined` —\n // the repo's tsconfig sets `exactOptionalPropertyTypes`, so an optional\n // `stats?` field must be omitted, not explicitly undefined.\n const collections: InspectorCollection[] = Object.entries(dump.collections).map(([name, desc]) => ({\n name,\n fields: desc.fields,\n indexes: desc.indexes,\n refs: desc.refs,\n ...(desc.stats !== undefined ? { stats: desc.stats } : {}),\n }))\n return { vault: dump.vault, collections }\n}\n","import type { Vault } from '@noy-db/hub'\nimport type { RecordPage } from './types.js'\n\nconst DEFAULT_LIMIT = 50\nconst MAX_LIMIT = 500\n\nfunction clampLimit(n: number | undefined): number {\n if (n === undefined || Number.isNaN(n)) return DEFAULT_LIMIT\n return Math.max(1, Math.min(MAX_LIMIT, Math.floor(n)))\n}\n\nfunction clampOffset(n: number | undefined): number {\n if (n === undefined || Number.isNaN(n) || n < 0) return 0\n return Math.floor(n)\n}\n\nexport async function records(\n vault: Vault,\n collection: string,\n opts: { limit?: number; offset?: number } = {},\n): Promise<RecordPage> {\n const limit = clampLimit(opts.limit)\n const offset = clampOffset(opts.offset)\n // Eager collections only — `list()` throws on lazy (prefetch:false). The\n // error propagates to the caller, which decides how to surface it.\n const all = await vault.collection(collection).list()\n return {\n rows: all.slice(offset, offset + limit),\n total: all.length,\n limit,\n offset,\n }\n}\n","import type { InspectorWriteEvent, InspectorWriteConflict, PendingWrites, InspectorNoydb } from './types.js'\n\nexport function subscribe(\n noydb: InspectorNoydb,\n handler: (event: InspectorWriteEvent) => void,\n): () => void {\n return noydb.onAfterWrite(handler)\n}\n\nexport function pendingWrites(noydb: InspectorNoydb): PendingWrites {\n const q = noydb.writeQueue\n return { pending: q.pending, depth: q.depth }\n}\n\nexport function subscribeConflicts(noydb: InspectorNoydb, handler: (c: InspectorWriteConflict) => void): () => void {\n return noydb.onWriteConflict(handler)\n}\n","import type { InspectorMeter } from './types.js'\nimport type { MeterSnapshot } from '@noy-db/to-meter'\n\nexport function meterSnapshot(meter: InspectorMeter | undefined): MeterSnapshot | null {\n return meter ? meter.snapshot() : null\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACGA,eAAsB,WAAW,OAA0D;AACzF,SAAO,MAAM,qBAAqB;AACpC;AAEA,eAAsB,SAAS,OAA0C;AAEvE,QAAM,OAAO,MAAM,MAAM,WAAW,EAAE,WAAW,KAAK,CAAC;AAIvD,QAAM,cAAqC,OAAO,QAAQ,KAAK,WAAW,EAAE,IAAI,CAAC,CAAC,MAAM,IAAI,OAAO;AAAA,IACjG;AAAA,IACA,QAAQ,KAAK;AAAA,IACb,SAAS,KAAK;AAAA,IACd,MAAM,KAAK;AAAA,IACX,GAAI,KAAK,UAAU,SAAY,EAAE,OAAO,KAAK,MAAM,IAAI,CAAC;AAAA,EAC1D,EAAE;AACF,SAAO,EAAE,OAAO,KAAK,OAAO,YAAY;AAC1C;;;AClBA,IAAM,gBAAgB;AACtB,IAAM,YAAY;AAElB,SAAS,WAAW,GAA+B;AACjD,MAAI,MAAM,UAAa,OAAO,MAAM,CAAC,EAAG,QAAO;AAC/C,SAAO,KAAK,IAAI,GAAG,KAAK,IAAI,WAAW,KAAK,MAAM,CAAC,CAAC,CAAC;AACvD;AAEA,SAAS,YAAY,GAA+B;AAClD,MAAI,MAAM,UAAa,OAAO,MAAM,CAAC,KAAK,IAAI,EAAG,QAAO;AACxD,SAAO,KAAK,MAAM,CAAC;AACrB;AAEA,eAAsB,QACpB,OACA,YACA,OAA4C,CAAC,GACxB;AACrB,QAAM,QAAQ,WAAW,KAAK,KAAK;AACnC,QAAM,SAAS,YAAY,KAAK,MAAM;AAGtC,QAAM,MAAM,MAAM,MAAM,WAAW,UAAU,EAAE,KAAK;AACpD,SAAO;AAAA,IACL,MAAM,IAAI,MAAM,QAAQ,SAAS,KAAK;AAAA,IACtC,OAAO,IAAI;AAAA,IACX;AAAA,IACA;AAAA,EACF;AACF;;;AC9BO,SAAS,UACd,OACA,SACY;AACZ,SAAO,MAAM,aAAa,OAAO;AACnC;AAEO,SAAS,cAAc,OAAsC;AAClE,QAAM,IAAI,MAAM;AAChB,SAAO,EAAE,SAAS,EAAE,SAAS,OAAO,EAAE,MAAM;AAC9C;AAEO,SAAS,mBAAmB,OAAuB,SAA0D;AAClH,SAAO,MAAM,gBAAgB,OAAO;AACtC;;;ACbO,SAAS,cAAc,OAAyD;AACrF,SAAO,QAAQ,MAAM,SAAS,IAAI;AACpC;;;AJEO,SAAS,gBAAgB,OAAuB,MAA8C;AACnG,SAAO;AAAA,IACL,YAAY,MAAM,WAAW,KAAK;AAAA,IAClC,UAAU,CAAC,UAAiB,SAAS,KAAK;AAAA,IAC1C,SAAS,CAAC,OAAO,YAAYA,UAAS,QAAQ,OAAO,YAAYA,KAAI;AAAA,IACrE,WAAW,CAAC,YAAY,UAAU,OAAO,OAAO;AAAA,IAChD,oBAAoB,CAAC,YAAY,mBAAmB,OAAO,OAAO;AAAA,IAClE,eAAe,MAAM,cAAc,KAAK;AAAA,IACxC,eAAe,MAAM,cAAc,MAAM,KAAK;AAAA,EAChD;AACF;","names":["opts"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { AccessibleVault, Vault, CollectionDescriptor, CollectionStats, WriteEvent, WriteConflict, Noydb } from '@noy-db/hub';
|
|
2
|
+
import { MeterSnapshot } from '@noy-db/to-meter';
|
|
3
|
+
|
|
4
|
+
/** Minimal structural view of a to-meter handle the inspector reads (no runtime dep). */
|
|
5
|
+
interface InspectorMeter {
|
|
6
|
+
snapshot(): MeterSnapshot;
|
|
7
|
+
}
|
|
8
|
+
/** Top-level accessible-vault entry (plain projection of the hub's AccessibleVault). */
|
|
9
|
+
type VaultInfo = AccessibleVault;
|
|
10
|
+
/**
|
|
11
|
+
* One collection in a snapshot — a flattened projection of the hub's
|
|
12
|
+
* CollectionDescriptor. Field/index/ref/stats shapes are derived directly from
|
|
13
|
+
* the hub types so they never drift.
|
|
14
|
+
*/
|
|
15
|
+
interface InspectorCollection {
|
|
16
|
+
readonly name: string;
|
|
17
|
+
readonly fields: CollectionDescriptor['fields'];
|
|
18
|
+
readonly indexes: CollectionDescriptor['indexes'];
|
|
19
|
+
readonly refs: CollectionDescriptor['refs'];
|
|
20
|
+
readonly stats?: CollectionStats;
|
|
21
|
+
}
|
|
22
|
+
/** Structure + stats for one open vault. */
|
|
23
|
+
interface InspectorSnapshot {
|
|
24
|
+
readonly vault: string;
|
|
25
|
+
readonly collections: ReadonlyArray<InspectorCollection>;
|
|
26
|
+
}
|
|
27
|
+
/** A page of decrypted records from one collection. */
|
|
28
|
+
interface RecordPage {
|
|
29
|
+
readonly rows: ReadonlyArray<unknown>;
|
|
30
|
+
readonly total: number;
|
|
31
|
+
readonly limit: number;
|
|
32
|
+
readonly offset: number;
|
|
33
|
+
}
|
|
34
|
+
/** Live write event surfaced to subscribers (the hub's public WriteEvent, unchanged — already plain). */
|
|
35
|
+
type InspectorWriteEvent = WriteEvent;
|
|
36
|
+
/** Write-conflict surfaced to conflict subscribers (the hub's public WriteConflict, unchanged — already plain). */
|
|
37
|
+
type InspectorWriteConflict = WriteConflict;
|
|
38
|
+
/** Pending-write state. */
|
|
39
|
+
interface PendingWrites {
|
|
40
|
+
readonly pending: boolean;
|
|
41
|
+
readonly depth: number;
|
|
42
|
+
}
|
|
43
|
+
/** The read-only inspector facade returned by createInspector(). */
|
|
44
|
+
interface Inspector {
|
|
45
|
+
listVaults(): Promise<ReadonlyArray<VaultInfo>>;
|
|
46
|
+
snapshot(vault: Vault): Promise<InspectorSnapshot>;
|
|
47
|
+
records(vault: Vault, collection: string, opts?: {
|
|
48
|
+
limit?: number;
|
|
49
|
+
offset?: number;
|
|
50
|
+
}): Promise<RecordPage>;
|
|
51
|
+
subscribe(handler: (event: InspectorWriteEvent) => void): () => void;
|
|
52
|
+
subscribeConflicts(handler: (c: InspectorWriteConflict) => void): () => void;
|
|
53
|
+
pendingWrites(): PendingWrites;
|
|
54
|
+
/** Aggregate store-op latency snapshot, or null when the store is not metered. */
|
|
55
|
+
meterSnapshot(): MeterSnapshot | null;
|
|
56
|
+
}
|
|
57
|
+
/** @internal — the hub handle the inspector reads from. */
|
|
58
|
+
type InspectorNoydb = Noydb;
|
|
59
|
+
|
|
60
|
+
declare function createInspector(noydb: InspectorNoydb, opts?: {
|
|
61
|
+
meter?: InspectorMeter;
|
|
62
|
+
}): Inspector;
|
|
63
|
+
|
|
64
|
+
export { type Inspector, type InspectorCollection, type InspectorMeter, type InspectorSnapshot, type InspectorWriteConflict, type InspectorWriteEvent, type PendingWrites, type RecordPage, type VaultInfo, createInspector };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { AccessibleVault, Vault, CollectionDescriptor, CollectionStats, WriteEvent, WriteConflict, Noydb } from '@noy-db/hub';
|
|
2
|
+
import { MeterSnapshot } from '@noy-db/to-meter';
|
|
3
|
+
|
|
4
|
+
/** Minimal structural view of a to-meter handle the inspector reads (no runtime dep). */
|
|
5
|
+
interface InspectorMeter {
|
|
6
|
+
snapshot(): MeterSnapshot;
|
|
7
|
+
}
|
|
8
|
+
/** Top-level accessible-vault entry (plain projection of the hub's AccessibleVault). */
|
|
9
|
+
type VaultInfo = AccessibleVault;
|
|
10
|
+
/**
|
|
11
|
+
* One collection in a snapshot — a flattened projection of the hub's
|
|
12
|
+
* CollectionDescriptor. Field/index/ref/stats shapes are derived directly from
|
|
13
|
+
* the hub types so they never drift.
|
|
14
|
+
*/
|
|
15
|
+
interface InspectorCollection {
|
|
16
|
+
readonly name: string;
|
|
17
|
+
readonly fields: CollectionDescriptor['fields'];
|
|
18
|
+
readonly indexes: CollectionDescriptor['indexes'];
|
|
19
|
+
readonly refs: CollectionDescriptor['refs'];
|
|
20
|
+
readonly stats?: CollectionStats;
|
|
21
|
+
}
|
|
22
|
+
/** Structure + stats for one open vault. */
|
|
23
|
+
interface InspectorSnapshot {
|
|
24
|
+
readonly vault: string;
|
|
25
|
+
readonly collections: ReadonlyArray<InspectorCollection>;
|
|
26
|
+
}
|
|
27
|
+
/** A page of decrypted records from one collection. */
|
|
28
|
+
interface RecordPage {
|
|
29
|
+
readonly rows: ReadonlyArray<unknown>;
|
|
30
|
+
readonly total: number;
|
|
31
|
+
readonly limit: number;
|
|
32
|
+
readonly offset: number;
|
|
33
|
+
}
|
|
34
|
+
/** Live write event surfaced to subscribers (the hub's public WriteEvent, unchanged — already plain). */
|
|
35
|
+
type InspectorWriteEvent = WriteEvent;
|
|
36
|
+
/** Write-conflict surfaced to conflict subscribers (the hub's public WriteConflict, unchanged — already plain). */
|
|
37
|
+
type InspectorWriteConflict = WriteConflict;
|
|
38
|
+
/** Pending-write state. */
|
|
39
|
+
interface PendingWrites {
|
|
40
|
+
readonly pending: boolean;
|
|
41
|
+
readonly depth: number;
|
|
42
|
+
}
|
|
43
|
+
/** The read-only inspector facade returned by createInspector(). */
|
|
44
|
+
interface Inspector {
|
|
45
|
+
listVaults(): Promise<ReadonlyArray<VaultInfo>>;
|
|
46
|
+
snapshot(vault: Vault): Promise<InspectorSnapshot>;
|
|
47
|
+
records(vault: Vault, collection: string, opts?: {
|
|
48
|
+
limit?: number;
|
|
49
|
+
offset?: number;
|
|
50
|
+
}): Promise<RecordPage>;
|
|
51
|
+
subscribe(handler: (event: InspectorWriteEvent) => void): () => void;
|
|
52
|
+
subscribeConflicts(handler: (c: InspectorWriteConflict) => void): () => void;
|
|
53
|
+
pendingWrites(): PendingWrites;
|
|
54
|
+
/** Aggregate store-op latency snapshot, or null when the store is not metered. */
|
|
55
|
+
meterSnapshot(): MeterSnapshot | null;
|
|
56
|
+
}
|
|
57
|
+
/** @internal — the hub handle the inspector reads from. */
|
|
58
|
+
type InspectorNoydb = Noydb;
|
|
59
|
+
|
|
60
|
+
declare function createInspector(noydb: InspectorNoydb, opts?: {
|
|
61
|
+
meter?: InspectorMeter;
|
|
62
|
+
}): Inspector;
|
|
63
|
+
|
|
64
|
+
export { type Inspector, type InspectorCollection, type InspectorMeter, type InspectorSnapshot, type InspectorWriteConflict, type InspectorWriteEvent, type PendingWrites, type RecordPage, type VaultInfo, createInspector };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
// src/snapshot.ts
|
|
2
|
+
async function listVaults(noydb) {
|
|
3
|
+
return noydb.listAccessibleVaults();
|
|
4
|
+
}
|
|
5
|
+
async function snapshot(vault) {
|
|
6
|
+
const dump = await vault.dumpSchema({ withStats: true });
|
|
7
|
+
const collections = Object.entries(dump.collections).map(([name, desc]) => ({
|
|
8
|
+
name,
|
|
9
|
+
fields: desc.fields,
|
|
10
|
+
indexes: desc.indexes,
|
|
11
|
+
refs: desc.refs,
|
|
12
|
+
...desc.stats !== void 0 ? { stats: desc.stats } : {}
|
|
13
|
+
}));
|
|
14
|
+
return { vault: dump.vault, collections };
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// src/records.ts
|
|
18
|
+
var DEFAULT_LIMIT = 50;
|
|
19
|
+
var MAX_LIMIT = 500;
|
|
20
|
+
function clampLimit(n) {
|
|
21
|
+
if (n === void 0 || Number.isNaN(n)) return DEFAULT_LIMIT;
|
|
22
|
+
return Math.max(1, Math.min(MAX_LIMIT, Math.floor(n)));
|
|
23
|
+
}
|
|
24
|
+
function clampOffset(n) {
|
|
25
|
+
if (n === void 0 || Number.isNaN(n) || n < 0) return 0;
|
|
26
|
+
return Math.floor(n);
|
|
27
|
+
}
|
|
28
|
+
async function records(vault, collection, opts = {}) {
|
|
29
|
+
const limit = clampLimit(opts.limit);
|
|
30
|
+
const offset = clampOffset(opts.offset);
|
|
31
|
+
const all = await vault.collection(collection).list();
|
|
32
|
+
return {
|
|
33
|
+
rows: all.slice(offset, offset + limit),
|
|
34
|
+
total: all.length,
|
|
35
|
+
limit,
|
|
36
|
+
offset
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// src/events.ts
|
|
41
|
+
function subscribe(noydb, handler) {
|
|
42
|
+
return noydb.onAfterWrite(handler);
|
|
43
|
+
}
|
|
44
|
+
function pendingWrites(noydb) {
|
|
45
|
+
const q = noydb.writeQueue;
|
|
46
|
+
return { pending: q.pending, depth: q.depth };
|
|
47
|
+
}
|
|
48
|
+
function subscribeConflicts(noydb, handler) {
|
|
49
|
+
return noydb.onWriteConflict(handler);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// src/meter.ts
|
|
53
|
+
function meterSnapshot(meter) {
|
|
54
|
+
return meter ? meter.snapshot() : null;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// src/index.ts
|
|
58
|
+
function createInspector(noydb, opts) {
|
|
59
|
+
return {
|
|
60
|
+
listVaults: () => listVaults(noydb),
|
|
61
|
+
snapshot: (vault) => snapshot(vault),
|
|
62
|
+
records: (vault, collection, opts2) => records(vault, collection, opts2),
|
|
63
|
+
subscribe: (handler) => subscribe(noydb, handler),
|
|
64
|
+
subscribeConflicts: (handler) => subscribeConflicts(noydb, handler),
|
|
65
|
+
pendingWrites: () => pendingWrites(noydb),
|
|
66
|
+
meterSnapshot: () => meterSnapshot(opts?.meter)
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
export {
|
|
70
|
+
createInspector
|
|
71
|
+
};
|
|
72
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/snapshot.ts","../src/records.ts","../src/events.ts","../src/meter.ts","../src/index.ts"],"sourcesContent":["import type { Vault } from '@noy-db/hub'\nimport type { InspectorSnapshot, InspectorCollection, VaultInfo, InspectorNoydb } from './types.js'\n\nexport async function listVaults(noydb: InspectorNoydb): Promise<ReadonlyArray<VaultInfo>> {\n return noydb.listAccessibleVaults()\n}\n\nexport async function snapshot(vault: Vault): Promise<InspectorSnapshot> {\n // withStats populates per-collection record/byte stats; opaque to the store.\n const dump = await vault.dumpSchema({ withStats: true })\n // Omit `stats` when absent rather than setting it to `undefined` —\n // the repo's tsconfig sets `exactOptionalPropertyTypes`, so an optional\n // `stats?` field must be omitted, not explicitly undefined.\n const collections: InspectorCollection[] = Object.entries(dump.collections).map(([name, desc]) => ({\n name,\n fields: desc.fields,\n indexes: desc.indexes,\n refs: desc.refs,\n ...(desc.stats !== undefined ? { stats: desc.stats } : {}),\n }))\n return { vault: dump.vault, collections }\n}\n","import type { Vault } from '@noy-db/hub'\nimport type { RecordPage } from './types.js'\n\nconst DEFAULT_LIMIT = 50\nconst MAX_LIMIT = 500\n\nfunction clampLimit(n: number | undefined): number {\n if (n === undefined || Number.isNaN(n)) return DEFAULT_LIMIT\n return Math.max(1, Math.min(MAX_LIMIT, Math.floor(n)))\n}\n\nfunction clampOffset(n: number | undefined): number {\n if (n === undefined || Number.isNaN(n) || n < 0) return 0\n return Math.floor(n)\n}\n\nexport async function records(\n vault: Vault,\n collection: string,\n opts: { limit?: number; offset?: number } = {},\n): Promise<RecordPage> {\n const limit = clampLimit(opts.limit)\n const offset = clampOffset(opts.offset)\n // Eager collections only — `list()` throws on lazy (prefetch:false). The\n // error propagates to the caller, which decides how to surface it.\n const all = await vault.collection(collection).list()\n return {\n rows: all.slice(offset, offset + limit),\n total: all.length,\n limit,\n offset,\n }\n}\n","import type { InspectorWriteEvent, InspectorWriteConflict, PendingWrites, InspectorNoydb } from './types.js'\n\nexport function subscribe(\n noydb: InspectorNoydb,\n handler: (event: InspectorWriteEvent) => void,\n): () => void {\n return noydb.onAfterWrite(handler)\n}\n\nexport function pendingWrites(noydb: InspectorNoydb): PendingWrites {\n const q = noydb.writeQueue\n return { pending: q.pending, depth: q.depth }\n}\n\nexport function subscribeConflicts(noydb: InspectorNoydb, handler: (c: InspectorWriteConflict) => void): () => void {\n return noydb.onWriteConflict(handler)\n}\n","import type { InspectorMeter } from './types.js'\nimport type { MeterSnapshot } from '@noy-db/to-meter'\n\nexport function meterSnapshot(meter: InspectorMeter | undefined): MeterSnapshot | null {\n return meter ? meter.snapshot() : null\n}\n","import type { Vault } from '@noy-db/hub'\nimport type { Inspector, InspectorNoydb, InspectorMeter } from './types.js'\nimport { listVaults, snapshot } from './snapshot.js'\nimport { records } from './records.js'\nimport { subscribe, subscribeConflicts, pendingWrites } from './events.js'\nimport { meterSnapshot } from './meter.js'\n\nexport function createInspector(noydb: InspectorNoydb, opts?: { meter?: InspectorMeter }): Inspector {\n return {\n listVaults: () => listVaults(noydb),\n snapshot: (vault: Vault) => snapshot(vault),\n records: (vault, collection, opts) => records(vault, collection, opts),\n subscribe: (handler) => subscribe(noydb, handler),\n subscribeConflicts: (handler) => subscribeConflicts(noydb, handler),\n pendingWrites: () => pendingWrites(noydb),\n meterSnapshot: () => meterSnapshot(opts?.meter),\n }\n}\n\nexport type {\n Inspector,\n VaultInfo,\n InspectorSnapshot,\n InspectorCollection,\n RecordPage,\n InspectorWriteEvent,\n InspectorWriteConflict,\n PendingWrites,\n InspectorMeter,\n} from './types.js'\n"],"mappings":";AAGA,eAAsB,WAAW,OAA0D;AACzF,SAAO,MAAM,qBAAqB;AACpC;AAEA,eAAsB,SAAS,OAA0C;AAEvE,QAAM,OAAO,MAAM,MAAM,WAAW,EAAE,WAAW,KAAK,CAAC;AAIvD,QAAM,cAAqC,OAAO,QAAQ,KAAK,WAAW,EAAE,IAAI,CAAC,CAAC,MAAM,IAAI,OAAO;AAAA,IACjG;AAAA,IACA,QAAQ,KAAK;AAAA,IACb,SAAS,KAAK;AAAA,IACd,MAAM,KAAK;AAAA,IACX,GAAI,KAAK,UAAU,SAAY,EAAE,OAAO,KAAK,MAAM,IAAI,CAAC;AAAA,EAC1D,EAAE;AACF,SAAO,EAAE,OAAO,KAAK,OAAO,YAAY;AAC1C;;;AClBA,IAAM,gBAAgB;AACtB,IAAM,YAAY;AAElB,SAAS,WAAW,GAA+B;AACjD,MAAI,MAAM,UAAa,OAAO,MAAM,CAAC,EAAG,QAAO;AAC/C,SAAO,KAAK,IAAI,GAAG,KAAK,IAAI,WAAW,KAAK,MAAM,CAAC,CAAC,CAAC;AACvD;AAEA,SAAS,YAAY,GAA+B;AAClD,MAAI,MAAM,UAAa,OAAO,MAAM,CAAC,KAAK,IAAI,EAAG,QAAO;AACxD,SAAO,KAAK,MAAM,CAAC;AACrB;AAEA,eAAsB,QACpB,OACA,YACA,OAA4C,CAAC,GACxB;AACrB,QAAM,QAAQ,WAAW,KAAK,KAAK;AACnC,QAAM,SAAS,YAAY,KAAK,MAAM;AAGtC,QAAM,MAAM,MAAM,MAAM,WAAW,UAAU,EAAE,KAAK;AACpD,SAAO;AAAA,IACL,MAAM,IAAI,MAAM,QAAQ,SAAS,KAAK;AAAA,IACtC,OAAO,IAAI;AAAA,IACX;AAAA,IACA;AAAA,EACF;AACF;;;AC9BO,SAAS,UACd,OACA,SACY;AACZ,SAAO,MAAM,aAAa,OAAO;AACnC;AAEO,SAAS,cAAc,OAAsC;AAClE,QAAM,IAAI,MAAM;AAChB,SAAO,EAAE,SAAS,EAAE,SAAS,OAAO,EAAE,MAAM;AAC9C;AAEO,SAAS,mBAAmB,OAAuB,SAA0D;AAClH,SAAO,MAAM,gBAAgB,OAAO;AACtC;;;ACbO,SAAS,cAAc,OAAyD;AACrF,SAAO,QAAQ,MAAM,SAAS,IAAI;AACpC;;;ACEO,SAAS,gBAAgB,OAAuB,MAA8C;AACnG,SAAO;AAAA,IACL,YAAY,MAAM,WAAW,KAAK;AAAA,IAClC,UAAU,CAAC,UAAiB,SAAS,KAAK;AAAA,IAC1C,SAAS,CAAC,OAAO,YAAYA,UAAS,QAAQ,OAAO,YAAYA,KAAI;AAAA,IACrE,WAAW,CAAC,YAAY,UAAU,OAAO,OAAO;AAAA,IAChD,oBAAoB,CAAC,YAAY,mBAAmB,OAAO,OAAO;AAAA,IAClE,eAAe,MAAM,cAAc,KAAK;AAAA,IACxC,eAAe,MAAM,cAAc,MAAM,KAAK;AAAA,EAChD;AACF;","names":["opts"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@noy-db/in-devtools",
|
|
3
|
+
"version": "0.2.0-pre.6",
|
|
4
|
+
"description": "Framework-agnostic read-only inspector for a live noy-db — vaults, collections, schema, stats, records, and live writes.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "./dist/index.cjs",
|
|
8
|
+
"module": "./dist/index.js",
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"import": {
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"default": "./dist/index.js"
|
|
15
|
+
},
|
|
16
|
+
"require": {
|
|
17
|
+
"types": "./dist/index.d.cts",
|
|
18
|
+
"default": "./dist/index.cjs"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"files": [
|
|
23
|
+
"dist"
|
|
24
|
+
],
|
|
25
|
+
"peerDependencies": {
|
|
26
|
+
"@noy-db/hub": "0.2.0-pre.6"
|
|
27
|
+
},
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"@noy-db/hub": "0.2.0-pre.6",
|
|
30
|
+
"@noy-db/to-meter": "0.2.0-pre.6"
|
|
31
|
+
},
|
|
32
|
+
"scripts": {
|
|
33
|
+
"build": "tsup",
|
|
34
|
+
"test": "vitest run",
|
|
35
|
+
"lint": "eslint src/",
|
|
36
|
+
"typecheck": "tsc --noEmit"
|
|
37
|
+
}
|
|
38
|
+
}
|