@typicalday/firegraph 0.1.0

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.
Files changed (48) hide show
  1. package/LICENSE +27 -0
  2. package/README.md +527 -0
  3. package/bin/firegraph.mjs +129 -0
  4. package/dist/chunk-KFA7G37W.js +443 -0
  5. package/dist/chunk-KFA7G37W.js.map +1 -0
  6. package/dist/chunk-YLGXLEUE.js +47 -0
  7. package/dist/chunk-YLGXLEUE.js.map +1 -0
  8. package/dist/client-Bk2Cm6xv.d.cts +131 -0
  9. package/dist/client-Bk2Cm6xv.d.ts +131 -0
  10. package/dist/codegen/index.cjs +81 -0
  11. package/dist/codegen/index.cjs.map +1 -0
  12. package/dist/codegen/index.d.cts +2 -0
  13. package/dist/codegen/index.d.ts +2 -0
  14. package/dist/codegen/index.js +7 -0
  15. package/dist/codegen/index.js.map +1 -0
  16. package/dist/editor/client/assets/index-DJJ_b0jI.js +411 -0
  17. package/dist/editor/client/assets/index-Q0QBYrMV.css +1 -0
  18. package/dist/editor/client/index.html +16 -0
  19. package/dist/editor/server/index.mjs +49597 -0
  20. package/dist/index-CG3R68Hu.d.cts +414 -0
  21. package/dist/index-CG3R68Hu.d.ts +414 -0
  22. package/dist/index.cjs +1953 -0
  23. package/dist/index.cjs.map +1 -0
  24. package/dist/index.d.cts +186 -0
  25. package/dist/index.d.ts +186 -0
  26. package/dist/index.js +1569 -0
  27. package/dist/index.js.map +1 -0
  28. package/dist/query-client/index.cjs +484 -0
  29. package/dist/query-client/index.cjs.map +1 -0
  30. package/dist/query-client/index.d.cts +15 -0
  31. package/dist/query-client/index.d.ts +15 -0
  32. package/dist/query-client/index.js +17 -0
  33. package/dist/query-client/index.js.map +1 -0
  34. package/dist/react.cjs +85 -0
  35. package/dist/react.cjs.map +1 -0
  36. package/dist/react.d.cts +44 -0
  37. package/dist/react.d.ts +44 -0
  38. package/dist/react.js +60 -0
  39. package/dist/react.js.map +1 -0
  40. package/dist/svelte.cjs +90 -0
  41. package/dist/svelte.cjs.map +1 -0
  42. package/dist/svelte.d.cts +46 -0
  43. package/dist/svelte.d.ts +46 -0
  44. package/dist/svelte.js +65 -0
  45. package/dist/svelte.js.map +1 -0
  46. package/dist/views-DL60k0cf.d.cts +91 -0
  47. package/dist/views-DL60k0cf.d.ts +91 -0
  48. package/package.json +122 -0
@@ -0,0 +1,414 @@
1
+ import { Timestamp, FieldValue, WhereFilterOp } from '@google-cloud/firestore';
2
+
3
+ /**
4
+ * Firegraph Configuration — project-level config file support.
5
+ *
6
+ * Projects create a `firegraph.config.ts` (or `.js`/`.mjs`) in their root:
7
+ *
8
+ * @example
9
+ * ```ts
10
+ * import { defineConfig } from 'firegraph';
11
+ *
12
+ * export default defineConfig({
13
+ * entities: './entities',
14
+ * project: 'my-project',
15
+ * collection: 'graph',
16
+ * });
17
+ * ```
18
+ */
19
+ /** Display contexts where views can appear. */
20
+ type ViewContext = 'listing' | 'detail' | 'inline';
21
+ /** View resolution configuration for a single entity type. */
22
+ interface ViewResolverConfig {
23
+ /** Default view name (e.g. 'card'). Falls back to 'json' if unset. */
24
+ default?: string;
25
+ /** View to use in NodeBrowser listing rows. */
26
+ listing?: string;
27
+ /** View to use on the NodeDetail page. */
28
+ detail?: string;
29
+ /** View to use for inline/embedded previews (edge rows, traversal). */
30
+ inline?: string;
31
+ }
32
+ /** Declarative view defaults, keyed by entity type. */
33
+ interface ViewDefaultsConfig {
34
+ /** Node view defaults keyed by aType (e.g. 'user', 'task'). */
35
+ nodes?: Record<string, ViewResolverConfig>;
36
+ /** Edge view defaults keyed by axbType (e.g. 'hasDeparture'). */
37
+ edges?: Record<string, ViewResolverConfig>;
38
+ }
39
+ /** Project-level firegraph configuration. */
40
+ interface FiregraphConfig {
41
+ /** Path to entities directory (per-entity folder convention). */
42
+ entities?: string;
43
+ /** GCP project ID. */
44
+ project?: string;
45
+ /** Firestore collection path (default: 'graph'). */
46
+ collection?: string;
47
+ /** Firestore emulator address (e.g. '127.0.0.1:8080'). */
48
+ emulator?: string;
49
+ /**
50
+ * Query execution backend.
51
+ *
52
+ * - `'pipeline'` (default) — Uses Firestore Pipeline API. Requires Enterprise
53
+ * Firestore. Enables indexless queries on `data.*` fields.
54
+ * - `'standard'` — Uses standard Firestore `.where().get()` queries. Not
55
+ * recommended for production. See README for risk details.
56
+ *
57
+ * When the emulator is active, always falls back to `'standard'`.
58
+ */
59
+ queryMode?: QueryMode;
60
+ /**
61
+ * AI chat configuration. Auto-detects `claude` CLI on PATH by default.
62
+ * Set to `false` to disable chat even if claude is available.
63
+ */
64
+ chat?: false | {
65
+ /** Claude model to use (default: 'sonnet'). */
66
+ model?: string;
67
+ /** Maximum concurrent claude processes (default: 2). */
68
+ maxConcurrency?: number;
69
+ };
70
+ /** Editor-specific settings. */
71
+ editor?: {
72
+ /** Server port (default: 3883). */
73
+ port?: number;
74
+ /** Force read-only mode. */
75
+ readonly?: boolean;
76
+ };
77
+ /** Declarative view defaults per entity type (overrides per-entity meta.json). */
78
+ viewDefaults?: ViewDefaultsConfig;
79
+ /**
80
+ * Dynamic registry mode. When set, the editor loads type definitions
81
+ * from Firestore meta-nodes in addition to filesystem entities.
82
+ * Filesystem types take precedence on name conflicts.
83
+ */
84
+ registryMode?: DynamicRegistryConfig;
85
+ }
86
+ /**
87
+ * Identity function providing type-checking and autocomplete for config files.
88
+ *
89
+ * @example
90
+ * ```ts
91
+ * import { defineConfig } from 'firegraph';
92
+ * export default defineConfig({ entities: './entities' });
93
+ * ```
94
+ */
95
+ declare function defineConfig(config: FiregraphConfig): FiregraphConfig;
96
+ /**
97
+ * Resolve which view to show for a given entity.
98
+ *
99
+ * 1. If `context` is provided and a context-specific default exists, use it.
100
+ * 2. Falls back to `resolverConfig.default`.
101
+ * 3. Ultimate fallback: `'json'`.
102
+ *
103
+ * Only returns view names that exist in `availableViewNames`.
104
+ */
105
+ declare function resolveView(resolverConfig: ViewResolverConfig | undefined, availableViewNames: string[], context?: ViewContext): string;
106
+
107
+ interface GraphRecord {
108
+ aType: string;
109
+ aUid: string;
110
+ axbType: string;
111
+ bType: string;
112
+ bUid: string;
113
+ data: Record<string, unknown>;
114
+ createdAt: Timestamp | FieldValue;
115
+ updatedAt: Timestamp | FieldValue;
116
+ }
117
+ interface StoredGraphRecord {
118
+ aType: string;
119
+ aUid: string;
120
+ axbType: string;
121
+ bType: string;
122
+ bUid: string;
123
+ data: Record<string, unknown>;
124
+ createdAt: Timestamp;
125
+ updatedAt: Timestamp;
126
+ }
127
+ interface WhereClause {
128
+ field: string;
129
+ op: '==' | '!=' | '<' | '<=' | '>' | '>=';
130
+ value: unknown;
131
+ }
132
+ interface FindEdgesParams {
133
+ aType?: string;
134
+ aUid?: string;
135
+ axbType?: string;
136
+ bType?: string;
137
+ bUid?: string;
138
+ limit?: number;
139
+ orderBy?: {
140
+ field: string;
141
+ direction?: 'asc' | 'desc';
142
+ };
143
+ where?: WhereClause[];
144
+ }
145
+ interface FindNodesParams {
146
+ aType: string;
147
+ }
148
+ interface QueryOptions {
149
+ limit?: number;
150
+ orderBy?: {
151
+ field: string;
152
+ direction?: 'asc' | 'desc';
153
+ };
154
+ }
155
+ type QueryPlan = {
156
+ strategy: 'get';
157
+ docId: string;
158
+ } | {
159
+ strategy: 'query';
160
+ filters: QueryFilter[];
161
+ options?: QueryOptions;
162
+ };
163
+ interface QueryFilter {
164
+ field: string;
165
+ op: WhereFilterOp;
166
+ value: unknown;
167
+ }
168
+ interface RegistryEntry {
169
+ aType: string;
170
+ axbType: string;
171
+ bType: string;
172
+ /** JSON Schema object for the data payload. */
173
+ jsonSchema?: object;
174
+ description?: string;
175
+ inverseLabel?: string;
176
+ /** Data field to use as the display title (e.g. 'name', 'date'). */
177
+ titleField?: string;
178
+ /** Data field to use as the display subtitle (e.g. 'status', 'difficulty'). */
179
+ subtitleField?: string;
180
+ }
181
+ /** Topology declaration for an edge (from edge.json). */
182
+ interface EdgeTopology {
183
+ from: string | string[];
184
+ to: string | string[];
185
+ inverseLabel?: string;
186
+ }
187
+ /** A discovered entity from the per-entity folder convention. */
188
+ interface DiscoveredEntity {
189
+ kind: 'node' | 'edge';
190
+ name: string;
191
+ /** Parsed JSON Schema for the data payload. */
192
+ schema: object;
193
+ /** Edge topology (only for edges). */
194
+ topology?: EdgeTopology;
195
+ description?: string;
196
+ /** Data field to use as the display title (e.g. 'name', 'date'). */
197
+ titleField?: string;
198
+ /** Data field to use as the display subtitle (e.g. 'status', 'difficulty'). */
199
+ subtitleField?: string;
200
+ /** View defaults from meta.json. */
201
+ viewDefaults?: ViewResolverConfig;
202
+ /** Absolute path to views.ts if present. */
203
+ viewsPath?: string;
204
+ /** Sample data from sample.json. */
205
+ sampleData?: Record<string, unknown>;
206
+ }
207
+ /** Result of scanning an entities directory. */
208
+ interface DiscoveryResult {
209
+ nodes: Map<string, DiscoveredEntity>;
210
+ edges: Map<string, DiscoveredEntity>;
211
+ }
212
+ /** Controls which Firestore query backend is used. */
213
+ type QueryMode = 'pipeline' | 'standard';
214
+ /**
215
+ * Configuration for dynamic registry mode where type definitions
216
+ * are stored as graph data (meta-nodes) rather than in code.
217
+ */
218
+ interface DynamicRegistryConfig {
219
+ mode: 'dynamic';
220
+ /**
221
+ * Collection path for meta-type nodes (`nodeType`, `edgeType`).
222
+ * Defaults to the main `collectionPath` if omitted.
223
+ */
224
+ collection?: string;
225
+ }
226
+ /** Options for defineNodeType / defineEdgeType beyond the core fields. */
227
+ interface DefineTypeOptions {
228
+ /** Data field to use as the display title (e.g. 'name', 'date'). */
229
+ titleField?: string;
230
+ /** Data field to use as the display subtitle (e.g. 'status', 'difficulty'). */
231
+ subtitleField?: string;
232
+ /** Mustache HTML template for rendering this type in the editor. */
233
+ viewTemplate?: string;
234
+ /** Scoped CSS for the view template (injected via Shadow DOM). */
235
+ viewCss?: string;
236
+ }
237
+ /** Data shape stored in a `nodeType` meta-node. */
238
+ interface NodeTypeData {
239
+ name: string;
240
+ jsonSchema: object;
241
+ description?: string;
242
+ titleField?: string;
243
+ subtitleField?: string;
244
+ viewTemplate?: string;
245
+ viewCss?: string;
246
+ }
247
+ /** Data shape stored in an `edgeType` meta-node. */
248
+ interface EdgeTypeData {
249
+ name: string;
250
+ from: string | string[];
251
+ to: string | string[];
252
+ jsonSchema?: object;
253
+ inverseLabel?: string;
254
+ description?: string;
255
+ titleField?: string;
256
+ subtitleField?: string;
257
+ viewTemplate?: string;
258
+ viewCss?: string;
259
+ }
260
+ interface GraphClientOptions {
261
+ /** Static registry built from code/discovery. Ignored if registryMode is set. */
262
+ registry?: GraphRegistry;
263
+ /** Dynamic registry mode — type definitions stored as graph data. */
264
+ registryMode?: DynamicRegistryConfig;
265
+ /**
266
+ * Query execution backend.
267
+ *
268
+ * - `'pipeline'` (default) — Uses Firestore Pipeline API. Requires Enterprise
269
+ * Firestore. Enables indexless queries on `data.*` fields.
270
+ * - `'standard'` — Uses standard Firestore `.where().get()` queries. Requires
271
+ * composite indexes for `data.*` filters or risks full collection scans
272
+ * (Enterprise) / query failures (Standard Firestore).
273
+ *
274
+ * When `FIRESTORE_EMULATOR_HOST` is set, the client auto-falls back to
275
+ * `'standard'` regardless of this setting (emulator doesn't support pipelines).
276
+ */
277
+ queryMode?: QueryMode;
278
+ }
279
+ interface GraphRegistry {
280
+ validate(aType: string, axbType: string, bType: string, data: unknown): void;
281
+ lookup(aType: string, axbType: string, bType: string): RegistryEntry | undefined;
282
+ entries(): ReadonlyArray<RegistryEntry>;
283
+ }
284
+ interface GraphReader {
285
+ getNode(uid: string): Promise<StoredGraphRecord | null>;
286
+ getEdge(aUid: string, axbType: string, bUid: string): Promise<StoredGraphRecord | null>;
287
+ edgeExists(aUid: string, axbType: string, bUid: string): Promise<boolean>;
288
+ findEdges(params: FindEdgesParams): Promise<StoredGraphRecord[]>;
289
+ findNodes(params: FindNodesParams): Promise<StoredGraphRecord[]>;
290
+ }
291
+ interface GraphWriter {
292
+ putNode(aType: string, uid: string, data: Record<string, unknown>): Promise<void>;
293
+ putEdge(aType: string, aUid: string, axbType: string, bType: string, bUid: string, data: Record<string, unknown>): Promise<void>;
294
+ updateNode(uid: string, data: Record<string, unknown>): Promise<void>;
295
+ removeNode(uid: string): Promise<void>;
296
+ removeEdge(aUid: string, axbType: string, bUid: string): Promise<void>;
297
+ }
298
+ interface GraphClient extends GraphReader, GraphWriter {
299
+ runTransaction<T>(fn: (tx: GraphTransaction) => Promise<T>): Promise<T>;
300
+ batch(): GraphBatch;
301
+ /** Delete a node and all its outgoing/incoming edges in chunked batches. */
302
+ removeNodeCascade(uid: string, options?: BulkOptions): Promise<CascadeResult>;
303
+ /** Find all edges matching `params` and delete them in chunked batches. */
304
+ bulkRemoveEdges(params: FindEdgesParams, options?: BulkOptions): Promise<BulkResult>;
305
+ }
306
+ interface DynamicGraphClient extends GraphClient {
307
+ /** Define or update a node type in the dynamic registry. */
308
+ defineNodeType(name: string, jsonSchema: object, description?: string, options?: DefineTypeOptions): Promise<void>;
309
+ /** Define or update an edge type in the dynamic registry. */
310
+ defineEdgeType(name: string, topology: EdgeTopology, jsonSchema?: object, description?: string, options?: DefineTypeOptions): Promise<void>;
311
+ /** Reload the registry from meta-type nodes in the graph. */
312
+ reloadRegistry(): Promise<void>;
313
+ }
314
+ interface GraphTransaction extends GraphReader, GraphWriter {
315
+ }
316
+ interface GraphBatch extends GraphWriter {
317
+ commit(): Promise<void>;
318
+ }
319
+ interface HopDefinition {
320
+ axbType: string;
321
+ direction?: 'forward' | 'reverse';
322
+ aType?: string;
323
+ bType?: string;
324
+ limit?: number;
325
+ orderBy?: {
326
+ field: string;
327
+ direction?: 'asc' | 'desc';
328
+ };
329
+ filter?: (edge: StoredGraphRecord) => boolean;
330
+ }
331
+ interface TraversalOptions {
332
+ maxReads?: number;
333
+ concurrency?: number;
334
+ returnIntermediates?: boolean;
335
+ }
336
+ interface HopResult {
337
+ axbType: string;
338
+ depth: number;
339
+ edges: StoredGraphRecord[];
340
+ sourceCount: number;
341
+ truncated: boolean;
342
+ }
343
+ interface TraversalResult {
344
+ nodes: StoredGraphRecord[];
345
+ hops: HopResult[];
346
+ totalReads: number;
347
+ truncated: boolean;
348
+ }
349
+ interface TraversalBuilder {
350
+ follow(axbType: string, options?: Omit<HopDefinition, 'axbType'>): TraversalBuilder;
351
+ run(options?: TraversalOptions): Promise<TraversalResult>;
352
+ }
353
+ interface BulkOptions {
354
+ /** Max operations per Firestore batch (default 500, Firestore hard limit). */
355
+ batchSize?: number;
356
+ /** Number of retry attempts per failed batch (default 3). */
357
+ maxRetries?: number;
358
+ /** Called after each batch commits. */
359
+ onProgress?: (progress: BulkProgress) => void;
360
+ }
361
+ interface BulkProgress {
362
+ /** Batches committed so far. */
363
+ completedBatches: number;
364
+ /** Total batches planned. */
365
+ totalBatches: number;
366
+ /** Total documents deleted so far. */
367
+ deletedSoFar: number;
368
+ }
369
+ interface BulkResult {
370
+ /** Total documents successfully deleted. */
371
+ deleted: number;
372
+ /** Number of batches committed. */
373
+ batches: number;
374
+ /** Errors from batches that failed after all retries. */
375
+ errors: BulkBatchError[];
376
+ }
377
+ interface BulkBatchError {
378
+ /** Zero-based index of the failed batch. */
379
+ batchIndex: number;
380
+ /** The underlying error. */
381
+ error: Error;
382
+ /** Number of operations in this batch that were not applied. */
383
+ operationCount: number;
384
+ }
385
+ interface CascadeResult extends BulkResult {
386
+ /** Number of edges deleted. */
387
+ edgesDeleted: number;
388
+ /** Whether the node itself was deleted. */
389
+ nodeDeleted: boolean;
390
+ }
391
+
392
+ /**
393
+ * Code generation — produces TypeScript type definitions from JSON Schema
394
+ * files discovered via the entity folder convention.
395
+ *
396
+ * Uses `json-schema-to-typescript` to compile each entity's `schema.json`
397
+ * into a TypeScript interface.
398
+ *
399
+ * Naming convention:
400
+ * - Nodes: `{PascalName}Data` (e.g. `TaskData`)
401
+ * - Edges: `{PascalName}EdgeData` (e.g. `HasStepEdgeData`)
402
+ */
403
+
404
+ interface CodegenOptions {
405
+ /** Add banner comment at top of output. Defaults to true. */
406
+ banner?: boolean;
407
+ }
408
+ /**
409
+ * Generate TypeScript type definitions from a DiscoveryResult.
410
+ * Returns the full file content as a string.
411
+ */
412
+ declare function generateTypes(discovery: DiscoveryResult, options?: CodegenOptions): Promise<string>;
413
+
414
+ export { defineConfig as A, type BulkBatchError as B, type CascadeResult as C, type DynamicRegistryConfig as D, type EdgeTopology as E, type FindEdgesParams as F, type GraphClientOptions as G, type HopDefinition as H, generateTypes as I, resolveView as J, type NodeTypeData as N, type QueryPlan as Q, type RegistryEntry as R, type StoredGraphRecord as S, type TraversalBuilder as T, type ViewContext as V, type WhereClause as W, type DynamicGraphClient as a, type GraphClient as b, type DiscoveryResult as c, type GraphRegistry as d, type GraphReader as e, type GraphRecord as f, type FindNodesParams as g, type BulkOptions as h, type BulkProgress as i, type BulkResult as j, type CodegenOptions as k, type DefineTypeOptions as l, type DiscoveredEntity as m, type EdgeTypeData as n, type FiregraphConfig as o, type GraphBatch as p, type GraphTransaction as q, type GraphWriter as r, type HopResult as s, type QueryFilter as t, type QueryMode as u, type QueryOptions as v, type TraversalOptions as w, type TraversalResult as x, type ViewDefaultsConfig as y, type ViewResolverConfig as z };