@rindle/devtools 0.1.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 +201 -0
- package/README.md +58 -0
- package/dist/ast.d.ts +10 -0
- package/dist/ast.d.ts.map +1 -0
- package/dist/ast.js +73 -0
- package/dist/ast.js.map +1 -0
- package/dist/core.d.ts +59 -0
- package/dist/core.d.ts.map +1 -0
- package/dist/core.js +351 -0
- package/dist/core.js.map +1 -0
- package/dist/global.d.ts +22 -0
- package/dist/global.d.ts.map +1 -0
- package/dist/global.js +60 -0
- package/dist/global.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +137 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/package.json +39 -0
- package/src/ast.ts +66 -0
- package/src/core.ts +388 -0
- package/src/global.ts +79 -0
- package/src/index.ts +30 -0
- package/src/types.ts +160 -0
package/src/types.ts
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
// The devtools read-model (DEBUG-TOOLS-BROWSER-DESIGN.md §4) and the read-only seams the core
|
|
2
|
+
// attaches to. Everything here is derived, in dev, from state the client already holds — the core
|
|
3
|
+
// adds no hot-path instrumentation (§1.1 "surface, not instrument").
|
|
4
|
+
|
|
5
|
+
import type { Ast, ChangeEvent, QueryId, ResultType, StoreDevObserver, StoreInspect } from "@rindle/client";
|
|
6
|
+
|
|
7
|
+
export type { Ast, ChangeEvent, FlatChange, FlatOp, QueryId, ResultType, StoreDevObserver, StoreInspect } from "@rindle/client";
|
|
8
|
+
|
|
9
|
+
// --- the attach target (duck-typed) ------------------------------------------------
|
|
10
|
+
// The core binds to a running client by structural type only — it never imports `@rindle/optimistic`
|
|
11
|
+
// (which would drag the wasm artifact into its typecheck). The optimistic backend's `__inspect()`
|
|
12
|
+
// shape below is kept IDENTICAL to `OptimisticInspect` in `@rindle/optimistic/backend.ts`; the two
|
|
13
|
+
// are cross-referenced by comment rather than a shared import to keep this package wasm-free.
|
|
14
|
+
|
|
15
|
+
/** One folded entry's debounce window — mirror of `@rindle/optimistic`'s `FoldInspect`. */
|
|
16
|
+
export interface FoldInspect {
|
|
17
|
+
foldKey: string;
|
|
18
|
+
debounceMs: number;
|
|
19
|
+
maxWaitMs?: number;
|
|
20
|
+
deferAcrossWrites: boolean;
|
|
21
|
+
flushed: boolean;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** One pending mutation — mirror of `@rindle/optimistic`'s `PendingInspect`. */
|
|
25
|
+
export interface PendingInspect {
|
|
26
|
+
key: string;
|
|
27
|
+
mid: number | null;
|
|
28
|
+
name: string;
|
|
29
|
+
args: unknown;
|
|
30
|
+
tables: string[];
|
|
31
|
+
fold?: FoldInspect;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** A snapshot of the optimistic loop — mirror of `@rindle/optimistic`'s `OptimisticInspect`. */
|
|
35
|
+
export interface OptimisticInspect {
|
|
36
|
+
pending: PendingInspect[];
|
|
37
|
+
confirmedLmid: number;
|
|
38
|
+
nextMid: number;
|
|
39
|
+
appliedCv: number;
|
|
40
|
+
bufferedFrames: number;
|
|
41
|
+
pendingTables: string[];
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** The Store surface the core reads (a structural subset of `@rindle/client`'s `Store`). */
|
|
45
|
+
export interface DevtoolsStore {
|
|
46
|
+
__attachDevtools(observer: StoreDevObserver): () => void;
|
|
47
|
+
__inspect(sampleRows?: number): StoreInspect;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** The optional optimistic-backend capability — present on `OptimisticBackend`, absent on a plain
|
|
51
|
+
* wasm/replica backend (then there is no mutation timeline, but queries + deltas still work). */
|
|
52
|
+
export interface DevtoolsBackend {
|
|
53
|
+
__inspect(): OptimisticInspect;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** What {@link attachDevtools} binds to: a `createRindleClient` app, or any `{ store, backend }`. */
|
|
57
|
+
export interface DevtoolsTarget {
|
|
58
|
+
store: DevtoolsStore;
|
|
59
|
+
/** Narrowed to {@link DevtoolsBackend} at runtime when it carries `__inspect` (capability probe). */
|
|
60
|
+
backend?: unknown;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// --- the read-model the panel renders ----------------------------------------------
|
|
64
|
+
|
|
65
|
+
/** A mutation's place in the fork/rebase lifecycle (DEBUG-TOOLS-BROWSER-DESIGN §4.1). */
|
|
66
|
+
export type MutationState = "pending" | "confirmed" | "dropped";
|
|
67
|
+
|
|
68
|
+
/** One row of the mutation timeline — the optimistic loop made visible. */
|
|
69
|
+
export interface TimelineEntry {
|
|
70
|
+
/** Stable identity across snapshots: the pending key (`m:<mid>` once a mid is dealt, else
|
|
71
|
+
* `f:<foldKey>` while a fold debounces). Retained after the entry settles. */
|
|
72
|
+
id: string;
|
|
73
|
+
/** The wire mutation id, or `null` for a still-folding entry. */
|
|
74
|
+
mid: number | null;
|
|
75
|
+
name: string;
|
|
76
|
+
args: unknown;
|
|
77
|
+
/** Tables the mutator touched (its pending-axis footprint). */
|
|
78
|
+
tables: string[];
|
|
79
|
+
state: MutationState;
|
|
80
|
+
/** True for a debounced/folded write; `fold` carries its window while it is live. */
|
|
81
|
+
folded: boolean;
|
|
82
|
+
fold?: FoldInspect;
|
|
83
|
+
/** Devtools-clock ms at first observation (invoke). */
|
|
84
|
+
invokedAt: number;
|
|
85
|
+
/** Devtools-clock ms when it left the pending stack (confirmed or dropped). */
|
|
86
|
+
settledAt?: number;
|
|
87
|
+
/** Heuristic (§4.1): view churn coincided with this mutation's confirmation — a POSSIBLE
|
|
88
|
+
* snap-back (the optimistic prediction diverged from the authoritative server result). Labeled
|
|
89
|
+
* "possible" because unrelated server data released in the same coherent batch also shows churn;
|
|
90
|
+
* a precise signal needs a reconcile-boundary event (a future engine seam). */
|
|
91
|
+
reconciledWithChurn: boolean;
|
|
92
|
+
/** qids of live queries whose tables this mutation touches (computed against the current views). */
|
|
93
|
+
affectedQueries: number[];
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/** One materialized view in the queries inspector (DEBUG-TOOLS-BROWSER-DESIGN §4.2). */
|
|
97
|
+
export interface QueryEntry {
|
|
98
|
+
qid: number;
|
|
99
|
+
ast: Ast;
|
|
100
|
+
/** The root table (`ast.table`). */
|
|
101
|
+
table: string;
|
|
102
|
+
/** A one-line human summary of the AST (table, filters, order, limit, relationships). */
|
|
103
|
+
summary: string;
|
|
104
|
+
/** Every base table the query reads (root + correlated subqueries). */
|
|
105
|
+
tables: string[];
|
|
106
|
+
resultType: ResultType;
|
|
107
|
+
rowCount: number;
|
|
108
|
+
sample: readonly unknown[];
|
|
109
|
+
/** Does any pending mutation touch this query's tables? (the §7.2 pending axis). */
|
|
110
|
+
pending: boolean;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/** The kind of a delta-stream row. `child` is an Add/Remove/Edit addressed at a NESTED path
|
|
114
|
+
* (`depth > 0`) — rindle's relationship-level change (DEBUG-TOOLS-BROWSER-DESIGN §4.3). */
|
|
115
|
+
export type DeltaKind = "hello" | "snapshot" | "add" | "remove" | "edit";
|
|
116
|
+
|
|
117
|
+
/** One entry of the live delta stream — the IVM change primitive made visible (§4.3). */
|
|
118
|
+
export interface DeltaEntry {
|
|
119
|
+
seq: number;
|
|
120
|
+
at: number;
|
|
121
|
+
qid: number;
|
|
122
|
+
kind: DeltaKind;
|
|
123
|
+
/** Nesting depth of the change path: 0 = top-level row, >0 = a child (relationship) change. */
|
|
124
|
+
depth: number;
|
|
125
|
+
/** A compact, human-readable description of the change. */
|
|
126
|
+
label: string;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/** The whole devtools snapshot a panel renders. Reference-stable arrays between updates where the
|
|
130
|
+
* underlying data did not change is NOT guaranteed — panels should treat each `getState()` as fresh. */
|
|
131
|
+
export interface DevtoolsState {
|
|
132
|
+
/** Newest-last mutation timeline (capped). */
|
|
133
|
+
timeline: TimelineEntry[];
|
|
134
|
+
/** Every live materialized view. */
|
|
135
|
+
queries: QueryEntry[];
|
|
136
|
+
/** Newest-last delta stream ring (capped). */
|
|
137
|
+
deltas: DeltaEntry[];
|
|
138
|
+
/** The raw optimistic-loop snapshot, when the backend exposes one (a "loop" summary line). */
|
|
139
|
+
optimistic?: OptimisticInspect;
|
|
140
|
+
capabilities: { optimistic: boolean };
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/** Construction options for {@link DevtoolsCore}. */
|
|
144
|
+
export interface DevtoolsCoreOptions {
|
|
145
|
+
/** Max timeline rows retained (oldest settled rows drop first). Default 200. */
|
|
146
|
+
timelineCap?: number;
|
|
147
|
+
/** Max delta-stream rows retained. Default 500. */
|
|
148
|
+
deltaCap?: number;
|
|
149
|
+
/** Per-query row sample size pulled from the store. Default 25. */
|
|
150
|
+
sampleRows?: number;
|
|
151
|
+
/** Safety-net poll interval (ms) that catches state moves with no event — a fold's debounced
|
|
152
|
+
* flush, or a pending flip on an already-`complete` query. Default 0 (off); {@link attachDevtools}
|
|
153
|
+
* turns it on. */
|
|
154
|
+
pollMs?: number;
|
|
155
|
+
/** Coalesce event-driven recomputes onto a microtask. Default true; tests pass `false` and drive
|
|
156
|
+
* recomputes explicitly via {@link DevtoolsCore.refresh}. */
|
|
157
|
+
autoFlush?: boolean;
|
|
158
|
+
/** Injectable clock (ms). Default `Date.now`; tests inject a deterministic counter. */
|
|
159
|
+
now?: () => number;
|
|
160
|
+
}
|