@zeronsh/orbit 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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../drizzle/src/cli/type-resolution.ts","../drizzle/src/cli/generate.ts"],"names":["path2"],"mappings":"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","file":"chunk-QR3NSGHJ.js","sourcesContent":["// Resolve each column's *TypeScript* type with the compiler (via ts-morph), so a\n// Drizzle `.$type<...>()` and enum unions survive into the generated schema —\n// information that does not exist at runtime. For column `c` of table exported as\n// `user`, we resolve `InferSelectModel<typeof user>['c']` (the canonical Drizzle\n// row-type accessor), strip nullability (Orbit models it with `optional()`), and\n// keep the result as the column's custom type. Named types it references (e.g.\n// `PostMeta`, or `import(\"…/country\").Country`) are rewritten to bare names and\n// collected as `import type` lines for the generated file.\n\nimport * as path from 'node:path';\n\nexport interface ResolveColumn {\n readonly jsKey: string;\n readonly dbName: string;\n readonly baseType: 'string' | 'number' | 'boolean' | 'json';\n}\n\nexport interface ResolveTable {\n /** The export name of the table in the schema module (e.g. `user`). */\n readonly exportName: string;\n /** The Orbit/database table name. */\n readonly tableName: string;\n readonly columns: readonly ResolveColumn[];\n}\n\nexport interface ResolveOptions {\n /** Absolute path to the user's Drizzle schema module. */\n readonly schemaModulePath: string;\n /** Absolute path of the file being generated (for relative import specifiers). */\n readonly outputFilePath: string;\n /** Optional tsconfig for module resolution. */\n readonly tsConfigFilePath?: string;\n /** Append `.js` to emitted relative import specifiers (Node16/NodeNext). */\n readonly jsExtension?: boolean;\n}\n\nexport interface ResolvedTypes {\n /** `tableName → dbColumnName → TS type expression`. */\n readonly customTypes: Record<string, Record<string, string>>;\n /** `import type` lines the generated file needs for named custom types. */\n readonly typeImports: { module: string; names: string[] }[];\n}\n\nconst TRIVIAL = new Set(['string', 'number', 'boolean', 'unknown', 'any', 'never', '{}', 'object']);\nconst NS = '__orbitDrizzleSchema';\n\nfunction stripNull(text: string): string {\n return text\n .replace(/\\s*\\|\\s*null\\b/g, '')\n .replace(/\\bnull\\s*\\|\\s*/g, '')\n .replace(/\\s*\\|\\s*undefined\\b/g, '')\n .trim();\n}\n\n/** Module specifier from `from` (the generated file) to `to` (a TS module). */\nfunction relSpecifier(fromFile: string, toModule: string, jsExtension: boolean): string {\n let rel = path.relative(path.dirname(fromFile), toModule).replace(/\\\\/g, '/');\n if (!rel.startsWith('.')) rel = `./${rel}`;\n rel = rel.replace(/\\.tsx?$/, '');\n return jsExtension ? `${rel}.js` : rel;\n}\n\nexport async function resolveCustomTypes(tables: readonly ResolveTable[], options: ResolveOptions): Promise<ResolvedTypes> {\n // ts-morph is an optional peer dependency; import lazily so the runtime path\n // never needs it.\n const { Project, ts } = await import('ts-morph');\n\n const project = options.tsConfigFilePath\n ? new Project({ tsConfigFilePath: options.tsConfigFilePath, skipAddingFilesFromTsConfig: true })\n : new Project({\n compilerOptions: { strict: true, moduleResolution: ts.ModuleResolutionKind.Bundler, target: ts.ScriptTarget.ES2022 },\n skipAddingFilesFromTsConfig: true,\n });\n\n project.addSourceFileAtPath(options.schemaModulePath);\n\n const schemaDir = path.dirname(options.schemaModulePath);\n const schemaSpecifier = `./${path.basename(options.schemaModulePath).replace(/\\.tsx?$/, '')}`;\n\n // One type alias per column, plus an index so we can map back.\n const aliases: { name: string; tableName: string; dbName: string; baseType: ResolveColumn['baseType'] }[] = [];\n let body = `import type { InferSelectModel } from 'drizzle-orm';\\nimport type * as ${NS} from ${JSON.stringify(schemaSpecifier)};\\n`;\n let i = 0;\n for (const t of tables) {\n for (const c of t.columns) {\n const name = `C_${i++}`;\n body += `type ${name} = InferSelectModel<typeof ${NS}.${t.exportName}>[${JSON.stringify(c.jsKey)}];\\n`;\n aliases.push({ name, tableName: t.tableName, dbName: c.dbName, baseType: c.baseType });\n }\n }\n\n const probe = project.createSourceFile(path.join(schemaDir, '__orbit_drizzle_probe__.ts'), body, { overwrite: true });\n const flags = ts.TypeFormatFlags.NoTruncation;\n\n const customTypes: Record<string, Record<string, string>> = {};\n // module specifier → set of imported names\n const importsByModule = new Map<string, Set<string>>();\n const addImport = (moduleSpecifier: string, name: string) => {\n const set = importsByModule.get(moduleSpecifier) ?? new Set<string>();\n set.add(name);\n importsByModule.set(moduleSpecifier, set);\n };\n\n for (const a of aliases) {\n const alias = probe.getTypeAliasOrThrow(a.name);\n const fullType = alias.getType();\n const constituents = fullType.isUnion() ? fullType.getUnionTypes() : [fullType];\n const nonNull = constituents.filter((c) => !c.isNull() && !c.isUndefined());\n\n // Keep a custom type only when it's a genuine *subtype* of the column's Orbit\n // base type. Otherwise the base type is the right one (e.g. a `timestamp`\n // maps to `number`, even though its Drizzle TS type is `Date`).\n const compatible =\n a.baseType === 'json'\n ? true\n : nonNull.length > 0 &&\n nonNull.every((c) => {\n if (a.baseType === 'string') return c.isString() || c.isStringLiteral() || c.isTemplateLiteral();\n if (a.baseType === 'number') return c.isNumber() || c.isNumberLiteral();\n return c.isBoolean() || c.isBooleanLiteral();\n });\n if (!compatible) continue;\n\n let text = stripNull(fullType.getText(alias, flags));\n\n // Rewrite `import(\"ABS\").Name` → `Name`, collecting an import from ABS.\n text = text.replace(/import\\(\"([^\"]+)\"\\)\\.(\\w+)/g, (_m, abs: string, name: string) => {\n const spec = relSpecifier(options.outputFilePath, abs, Boolean(options.jsExtension));\n addImport(spec, name);\n return name;\n });\n\n // Rewrite `__orbitDrizzleSchema.Name` → `Name`, importing from the schema module.\n const schemaImportSpec = relSpecifier(options.outputFilePath, options.schemaModulePath, Boolean(options.jsExtension));\n text = text.replace(new RegExp(`${NS}\\\\.(\\\\w+)`, 'g'), (_m, name: string) => {\n addImport(schemaImportSpec, name);\n return name;\n });\n\n // Drop trivial types; for json keep only meaningful object/array/named types.\n if (TRIVIAL.has(text) || text === '') continue;\n if (a.baseType === 'json' && (text === 'unknown' || text === 'any')) continue;\n\n (customTypes[a.tableName] ??= {})[a.dbName] = text;\n }\n\n project.removeSourceFile(probe);\n\n const typeImports = [...importsByModule.entries()].map(([module, names]) => ({ module, names: [...names].sort() }));\n return { customTypes, typeImports };\n}\n","// The `orbit-drizzle generate` pipeline:\n// import schema (runtime) → resolve custom types (ts-morph) → IR → emit → write.\n\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport { getTableColumns, getTableName, is, Table } from 'drizzle-orm';\nimport { emitSchema } from '../../../orm-core/src/index.ts';\nimport { drizzleToIR, type DrizzleAdapterConfig } from '../introspect.ts';\nimport { orbitTypeOf, type DrizzleColumnLike } from '../type-map.ts';\nimport { resolveCustomTypes, type ResolveTable } from './type-resolution.ts';\n\nexport interface GenerateOptions {\n /** Path to the Drizzle schema module (a single `.ts` file exporting tables + relations). */\n readonly schemaPath: string;\n /** Output path. Default `./orbit-schema.gen.ts`. */\n readonly outputPath?: string;\n /** tsconfig for type resolution + module resolution. */\n readonly tsConfigPath?: string;\n /** Run Prettier over the output if available. */\n readonly format?: boolean;\n /** Append `.js` to relative imports (Node16/NodeNext ESM). */\n readonly jsExtension?: boolean;\n /** Module the Orbit schema helpers are imported from. Default `@orbit/client`. */\n readonly importFrom?: string;\n /** Exported schema const name. Default `schema`. */\n readonly schemaName?: string;\n /** Table/column selection (see {@link DrizzleAdapterConfig.tables}). */\n readonly tables?: DrizzleAdapterConfig['tables'];\n readonly debug?: boolean;\n}\n\nexport interface GenerateResult {\n readonly outputPath: string;\n readonly source: string;\n}\n\n/** Generate an Orbit schema source file from a Drizzle schema. */\nexport async function generate(options: GenerateOptions): Promise<GenerateResult> {\n const schemaModulePath = path.resolve(options.schemaPath);\n const outputPath = path.resolve(options.outputPath ?? './orbit-schema.gen.ts');\n\n // 1. Load the schema module at runtime (tables + relations).\n const moduleObj = (await import(pathToFileURL(schemaModulePath).href)) as Record<string, unknown>;\n\n // 2. Collect per-table resolution metadata (export name, jsKey ↔ dbName).\n const resolveTables: ResolveTable[] = [];\n for (const [exportName, value] of Object.entries(moduleObj)) {\n if (!is(value, Table)) continue;\n const table = value as Table;\n const tableName = getTableName(table);\n if (options.tables && options.tables[tableName] === false) continue;\n const cols = getTableColumns(table) as Record<string, DrizzleColumnLike & { name: string }>;\n const columns = Object.entries(cols)\n .map(([jsKey, col]) => {\n const base = orbitTypeOf(col);\n return base ? { jsKey, dbName: col.name, baseType: base } : null;\n })\n .filter((c): c is NonNullable<typeof c> => c !== null);\n resolveTables.push({ exportName, tableName, columns });\n }\n\n // 3. Resolve custom `$type<>()` / enum types via the TypeScript compiler.\n const { customTypes, typeImports } = await resolveCustomTypes(resolveTables, {\n schemaModulePath,\n outputFilePath: outputPath,\n tsConfigFilePath: options.tsConfigPath,\n jsExtension: options.jsExtension,\n });\n\n // 4. Build the IR with the resolved custom types folded in.\n const ir = drizzleToIR(moduleObj, { customTypes, tables: options.tables, debug: options.debug });\n\n // 5. Emit the Orbit schema source.\n let source = emitSchema(ir, {\n importFrom: options.importFrom ?? '@zeronsh/orbit/client',\n schemaName: options.schemaName,\n jsExtension: options.jsExtension,\n typeImports,\n header: [\n `Generated by @orbit/drizzle from ${path.basename(schemaModulePath)} — do not edit by hand.`,\n `Re-run \\`orbit-drizzle generate\\` to update.`,\n ],\n });\n\n // 6. Optional Prettier.\n if (options.format) source = await formatWithPrettier(source, outputPath);\n\n await fs.writeFile(outputPath, source, 'utf8');\n return { outputPath, source };\n}\n\nasync function formatWithPrettier(source: string, filepath: string): Promise<string> {\n try {\n const prettier = await import('prettier');\n const config = (await prettier.resolveConfig(filepath)) ?? {};\n return prettier.format(source, { ...config, parser: 'typescript' });\n } catch {\n console.warn('⚠️ orbit-drizzle: prettier not found — skipping formatting.');\n return source;\n }\n}\n"]}
@@ -0,0 +1,349 @@
1
+ import { a as QueriesPatchOp, R as Row, b as RowPatchOp, C as CrudOp, M as Mutation, c as QueryHost, d as SchemaQueries, e as Query, A as AST, V as Value, O as OrderPart } from './query-BMK1cXAS.js';
2
+ export { f as Condition, g as CorrelatedSubquery, h as Correlation, D as Direction, i as Downstream, P as PROTOCOL_VERSION, Q as QueryBuilder, j as SchemaQuery, k as SimpleOperator, S as Subscribable, T as TypedQuery, U as Upstream, l as ValuePosition, m as ViewLike, n as buildSchemaQueries, o as createBuilder, p as hashAST, q as hashString } from './query-BMK1cXAS.js';
3
+ import { S as SchemaDef, R as RowOf, P as PkOf, A as AnySchema } from './schema-BNM6bks7.js';
4
+ export { b as Cardinality, c as Column, d as Columns, C as Connection, a as Relationship, e as RelationshipsDef, f as RelationshipsMap, T as TableDef, V as ValueType, g as boolean, h as createSchema, j as json, n as number, o as optional, r as relationships, s as string, t as table } from './schema-BNM6bks7.js';
5
+ import { a as MutatorDefs, b as QueryDefs, c as QueriesAPI, d as MutateAPI } from './custom-DzMQ-nY2.js';
6
+ export { M as MutatorDef, Q as QueryDef, S as SchemaCRUD, T as TableCRUD, e as Transaction, f as collectOps, g as defineMutator, h as defineQuery } from './custom-DzMQ-nY2.js';
7
+
8
+ /** The `put` variant of a desired-query patch op (always has a `hash`). */
9
+ type QueryPut = Extract<QueriesPatchOp, {
10
+ op: 'put';
11
+ }>;
12
+ type TTL = number | `${number}${'s' | 'm' | 'h' | 'd'}` | 'forever' | 'none';
13
+ /** Parse a TTL into milliseconds. `'forever'` → Infinity, `'none'`/0 → 0. */
14
+ declare function parseTTL(ttl: TTL): number;
15
+ type Scheduler = {
16
+ setTimeout: (fn: () => void, ms: number) => unknown;
17
+ clearTimeout: (handle: unknown) => void;
18
+ };
19
+ declare class QueryManager {
20
+ #private;
21
+ constructor(opts: {
22
+ onSubscribe: (put: QueryPut) => void;
23
+ onUnsubscribe: (hash: string) => void;
24
+ scheduler?: Scheduler;
25
+ });
26
+ /**
27
+ * Register interest in a query. Returns a release function (idempotent). The
28
+ * first registration subscribes upstream; identical queries dedupe to one.
29
+ */
30
+ add(hash: string, put: QueryPut, ttl?: TTL): () => void;
31
+ /** All currently-subscribed query `put` ops (for reconnect resume). */
32
+ active(): QueryPut[];
33
+ /** Number of live (subscribed, incl. within-TTL) queries — for tests/introspection. */
34
+ size(): number;
35
+ }
36
+
37
+ interface KV {
38
+ get(key: string): Promise<unknown>;
39
+ set(key: string, value: unknown): Promise<void>;
40
+ del(key: string): Promise<void>;
41
+ /** All `[key, value]` pairs whose key starts with `prefix`. */
42
+ entries(prefix: string): Promise<[string, unknown][]>;
43
+ }
44
+ /** In-memory KV — used by tests and as a no-IndexedDB fallback. */
45
+ declare class MemoryKV implements KV {
46
+ #private;
47
+ get(key: string): Promise<unknown>;
48
+ set(key: string, value: unknown): Promise<void>;
49
+ del(key: string): Promise<void>;
50
+ entries(prefix: string): Promise<[string, unknown][]>;
51
+ }
52
+ /** IndexedDB-backed KV (browser). One object store, keyed by string. */
53
+ declare class IDBKV implements KV {
54
+ #private;
55
+ constructor(name?: string);
56
+ get(key: string): Promise<unknown>;
57
+ set(key: string, value: unknown): Promise<void>;
58
+ del(key: string): Promise<void>;
59
+ entries(prefix: string): Promise<[string, unknown][]>;
60
+ }
61
+
62
+ /** A changed effective-row key, delivered to listeners so views update incrementally. */
63
+ type ChangedKey = {
64
+ table: string;
65
+ key: string;
66
+ };
67
+ type Listener = (changed: ReadonlyArray<ChangedKey>) => void;
68
+ declare class Store {
69
+ #private;
70
+ constructor(pkByTable?: Record<string, string[]>);
71
+ /** Primary-key columns for a table (for complete ordering in the evaluator). */
72
+ pkOf(table: string): string[];
73
+ /** Public pk-key for a row (used by the IVM-backed view to match changes). */
74
+ keyOf(table: string, row: Row): string;
75
+ /** The effective (synced + optimistic overlay) row for a pk key, or undefined. */
76
+ effectiveRow(table: string, key: string): Row | undefined;
77
+ apply(op: RowPatchOp): void;
78
+ applyAll(ops: RowPatchOp[]): void;
79
+ /** Queue an optimistic mutation's CRUD ops (applied on top of synced rows). */
80
+ addPending(id: number, ops: CrudOp[], mutation?: Mutation): void;
81
+ /** Drop pending mutations the server has confirmed (id <= confirmed). */
82
+ confirmThrough(id: number): void;
83
+ /** Originating messages of still-pending mutations (for resend after reload). */
84
+ pendingMutations(): Mutation[];
85
+ /** All rows for `table` with the optimistic overlay applied. */
86
+ effectiveRows(table: string): Row[];
87
+ subscribe(fn: Listener): () => void;
88
+ /** Load persisted rows + pending mutations from `kv` into memory. */
89
+ hydrate(kv: KV): Promise<void>;
90
+ /** Flush dirty rows + pending mutations to the KV (called debounced). */
91
+ flush(): Promise<void>;
92
+ }
93
+
94
+ type OrbitOptions<S extends SchemaDef = AnySchema> = {
95
+ server: string;
96
+ /** The schema — supplies end-to-end types for `query`/`mutate`. Optional. */
97
+ schema?: S;
98
+ /**
99
+ * Auth token (or async getter) sent to the server, which forwards it as a
100
+ * `Bearer` token to your push/query endpoints so they can authenticate.
101
+ */
102
+ auth?: string | (() => string | Promise<string>);
103
+ clientID?: string;
104
+ clientGroupID?: string;
105
+ /** Max reconnect backoff in ms (default 30s). Set 0 to disable reconnect. */
106
+ maxReconnectMs?: number;
107
+ /**
108
+ * How long a query stays subscribed after its last view is destroyed, before
109
+ * it's garbage-collected (a `del` is sent upstream). Default `'5m'`.
110
+ */
111
+ queryTTL?: TTL;
112
+ /**
113
+ * Persist synced rows + pending mutations to a `KV` (e.g. `new IDBKV()` in the
114
+ * browser) so data is available offline and survives reloads. Hydrated before
115
+ * the first connection.
116
+ */
117
+ persist?: KV;
118
+ /**
119
+ * Called when the server sends a terminal `error` message (e.g. auth/version
120
+ * failure). Without a handler the error is logged; the socket still reconnects
121
+ * with backoff, so handle fatal errors here (e.g. refresh auth or `close()`).
122
+ */
123
+ onError?: (e: {
124
+ kind: string;
125
+ message: string;
126
+ }) => void;
127
+ };
128
+ /** Per-table CRUD mutators, mirroring Zero's `z.mutate.<table>.<op>(row)`. */
129
+ type TableMutator<T extends Row = Row, PK extends keyof T = keyof T> = {
130
+ insert(value: T): void;
131
+ upsert(value: T): void;
132
+ update(value: Pick<T, PK> & Partial<T>): void;
133
+ delete(value: Pick<T, PK>): void;
134
+ };
135
+ /** `orbit.query.<table>` — one schema-aware query per table (relationships by name). */
136
+ type QueryAccess<S extends SchemaDef> = SchemaQueries<S>;
137
+ /** `orbit.mutate.<table>` — one typed mutator per schema table. */
138
+ type MutateAccess<S extends SchemaDef> = {
139
+ [K in keyof S['tables']]: TableMutator<RowOf<S['tables'][K]>, PkOf<S['tables'][K]>>;
140
+ };
141
+ /**
142
+ * A live view over a query's results, maintained **incrementally** by the IVM
143
+ * operator graph (see `ivm/`). The query is compiled to a pipeline of operators
144
+ * fed by the local store; each store change is pushed through as add/remove/edit
145
+ * and the materialized result is updated in place — not re-evaluated from
146
+ * scratch. `applyWhere` defaults to true (the client store is shared across
147
+ * subscriptions, so each view must filter to its own rows); pass false only when
148
+ * the caller guarantees the store already holds exactly this query's rows.
149
+ */
150
+ declare class View<T extends Row = Row> {
151
+ #private;
152
+ data: T[];
153
+ constructor(store: Store, ast: AST, applyWhere?: boolean, onDestroy?: () => void);
154
+ subscribe(fn: () => void): () => void;
155
+ /** Stop reacting to store changes + release the query subscription (Zero's `view.destroy()`). */
156
+ destroy(): void;
157
+ }
158
+ declare class Orbit<S extends SchemaDef = AnySchema, MD extends MutatorDefs | undefined = undefined, QD extends QueryDefs | undefined = undefined> implements QueryHost {
159
+ #private;
160
+ clientID: string;
161
+ clientGroupID: string;
162
+ /** Per-table typed query builder (ad-hoc queries): `orbit.query.todo.where(...)`. */
163
+ readonly query: QueryAccess<S>;
164
+ /** Custom (named) queries from the `queries` option: `orbit.queries.allTodos()`. */
165
+ readonly queries: QD extends QueryDefs ? QueriesAPI<QD> : Record<string, never>;
166
+ /**
167
+ * Mutators. With a `mutators` option these are your custom mutators
168
+ * (`orbit.mutate.createTodo(args)`); otherwise per-table CRUD
169
+ * (`orbit.mutate.todo.insert(...)`).
170
+ */
171
+ readonly mutate: MD extends MutatorDefs ? MutateAPI<MD> : MutateAccess<S>;
172
+ constructor(opts: OrbitOptions<S> & {
173
+ mutators?: MD;
174
+ queries?: QD;
175
+ });
176
+ /** Build a raw (untyped) query against `table` — escape hatch. */
177
+ queryRaw(table: string): Query;
178
+ /** Subscribe to an ad-hoc query and return a live [`View`]. */
179
+ materialize(query: Query, ttl?: TTL): View;
180
+ /**
181
+ * Subscribe to a custom (named) query by name + args. The server's query
182
+ * endpoint resolves/authorizes it (with the connection's auth) into the actual
183
+ * query; the client uses the def's `ast` for local ordering/nesting/optimism.
184
+ *
185
+ * The local view DOES apply the def's `where` (applyWhere=true): the client
186
+ * store is shared across all subscriptions, so without it a filtered query like
187
+ * `issue({id})` would match every row another query synced (e.g. the issues
188
+ * list) and `.one()` would return the wrong row. This assumes the def's filter
189
+ * matches the server's resolution, which holds for ordinary parameterized
190
+ * queries; the store only ever holds server-authorized rows.
191
+ */
192
+ materializeNamed(name: string, args: unknown[], ast: AST, ttl?: TTL): View;
193
+ /** Apply a single CRUD op (mirrors `z.mutate.<table>.insert(...)`). */
194
+ mutateCrud(op: CrudOp): void;
195
+ /** Run a custom mutator by name (optimistically, then on the server). */
196
+ mutateCustom(name: string, args?: unknown): void;
197
+ close(): void;
198
+ }
199
+
200
+ /** A nested query result row: columns plus any `related` arrays under their alias. */
201
+ type ResultRow = Record<string, unknown>;
202
+ /** Total order with `null == null` (sorting semantics; mirrors `compare_values`). */
203
+ declare function compareValues(a: Value, b: Value): number;
204
+ /** Equality with `null != null` (join / `=` semantics; mirrors `values_equal`). */
205
+ declare function valuesEqual(a: Value, b: Value): boolean;
206
+ /**
207
+ * Evaluate `ast` against `getRows` (a function returning all current rows of a
208
+ * table). Returns nested result rows. Set `applyWhere: false` for server-resolved
209
+ * (named) queries whose `where` was already applied server-side.
210
+ */
211
+ declare function evaluate(getRows: (table: string) => Row[], ast: AST, opts?: {
212
+ applyWhere?: boolean;
213
+ pkOf?: (table: string) => readonly string[];
214
+ }): ResultRow[];
215
+ /**
216
+ * Unwrap `.one()` relationships in a result tree to a single row (or `undefined`),
217
+ * recursively. The raw materialized shape keeps relationships as arrays (matching
218
+ * the server/IVM snapshot); this is the client-facing presentation transform.
219
+ */
220
+ declare function unwrapSingular(rows: ResultRow[], ast: AST): ResultRow[];
221
+
222
+ /** A row flowing through the pipeline plus its (eagerly materialized) children. */
223
+ type Node = {
224
+ row: Row;
225
+ relationships: Record<string, Node[]>;
226
+ };
227
+ /** An incremental change propagated downstream through `push`. */
228
+ type Change = {
229
+ type: 'add';
230
+ node: Node;
231
+ } | {
232
+ type: 'remove';
233
+ node: Node;
234
+ } | {
235
+ type: 'edit';
236
+ node: Node;
237
+ oldNode: Node;
238
+ } | {
239
+ type: 'child';
240
+ node: Node;
241
+ relationshipName: string;
242
+ change: Change;
243
+ };
244
+ /** A change applied to a Source (bare rows — sources are leaves). */
245
+ type SourceChange = {
246
+ type: 'add';
247
+ row: Row;
248
+ } | {
249
+ type: 'remove';
250
+ row: Row;
251
+ } | {
252
+ type: 'edit';
253
+ row: Row;
254
+ oldRow: Row;
255
+ };
256
+ /** Parameters for a fetch (pull). */
257
+ type FetchRequest = {
258
+ constraint?: Record<string, Value>;
259
+ start?: {
260
+ row: Row;
261
+ basis: 'at' | 'after';
262
+ };
263
+ reverse?: boolean;
264
+ };
265
+ /** An operator: both the fetch (pull) and push sides, plus a downstream link. */
266
+ interface Op {
267
+ fetch(req: FetchRequest): Node[];
268
+ push(change: Change): Change[];
269
+ output: Op | null;
270
+ setOutput(o: Op): void;
271
+ }
272
+ type Comparator = (a: Row, b: Row) => number;
273
+
274
+ /** Supplies a source connection + primary key for each table in an AST. */
275
+ interface SourceProvider {
276
+ pkOf(table: string): string[];
277
+ connect(table: string, order: OrderPart[]): Op;
278
+ }
279
+ declare function buildPipeline(ast: AST, provider: SourceProvider, partitionKey?: string[] | null): Op;
280
+
281
+ declare class MaterializedView {
282
+ #private;
283
+ /** The current top-level result, in sort order. */
284
+ nodes: Node[];
285
+ constructor(top: Op, order: OrderPart[], pk: string[]);
286
+ /** The result as Zero's `{row, rels}` snapshot shape (hidden `zsubq_*` excluded). */
287
+ snapshot(): {
288
+ row: Row;
289
+ rels: Record<string, unknown>;
290
+ }[];
291
+ }
292
+
293
+ type Connection = {
294
+ output: Op | null;
295
+ order: OrderPart[];
296
+ cmp: Comparator;
297
+ };
298
+ declare class MemorySource {
299
+ #private;
300
+ readonly table: string;
301
+ readonly pk: string[];
302
+ constructor(table: string, pk: string[]);
303
+ insertInitial(row: Row): void;
304
+ rows(): Row[];
305
+ get(key: string): Row | undefined;
306
+ connect(order: OrderPart[]): SourceConnection;
307
+ fetchConn(req: FetchRequest, conn: Connection): Node[];
308
+ /** Apply a source change (commit-first) and propagate to all connections. */
309
+ push(change: SourceChange): void;
310
+ }
311
+ /** A set of MemorySources, one per table — a `SourceProvider` for the builder. */
312
+ declare class MemorySourceProvider {
313
+ #private;
314
+ add(table: string, pk: string[], rows: Row[]): MemorySource;
315
+ source(table: string): MemorySource;
316
+ pkOf(table: string): string[];
317
+ connect(table: string, order: OrderPart[]): Op;
318
+ push(table: string, change: SourceChange): void;
319
+ }
320
+ /** One connection (consumer) of a MemorySource — an Input + push target. */
321
+ declare class SourceConnection implements Op {
322
+ #private;
323
+ output: Op | null;
324
+ constructor(src: MemorySource, conn: Connection);
325
+ fetch(req: FetchRequest): Node[];
326
+ push(): Change[];
327
+ setOutput(o: Op): void;
328
+ }
329
+
330
+ declare class StoreProvider implements SourceProvider {
331
+ #private;
332
+ constructor(store: Store);
333
+ pkOf(table: string): string[];
334
+ connect(table: string, order: OrderPart[]): Op;
335
+ /** Push the change for one touched effective-row key into its table's source. */
336
+ applyChange(table: string, key: string): void;
337
+ }
338
+ /** Tables referenced anywhere in an AST (top + related + EXISTS subqueries). */
339
+ declare function tablesOf(ast: AST, out?: Set<string>): Set<string>;
340
+ /** Convert an IVM result node into a client row (nested arrays, singular unwrap). */
341
+ declare function nodeToRow(node: {
342
+ row: Row;
343
+ relationships: Record<string, {
344
+ row: Row;
345
+ relationships: Record<string, unknown>;
346
+ }[]>;
347
+ }, ast: AST): Record<string, unknown>;
348
+
349
+ export { AST, AnySchema, type Change, type Comparator, CrudOp, type FetchRequest, IDBKV, type KV, MaterializedView, MemoryKV, MemorySource, MemorySourceProvider, MutateAPI, type MutateAccess, Mutation, MutatorDefs, type Node, type Op, Orbit, type OrbitOptions, OrderPart, PkOf, QueriesAPI, QueriesPatchOp, Query, type QueryAccess, QueryDefs, QueryHost, QueryManager, type QueryPut, type ResultRow, Row, RowOf, RowPatchOp, type Scheduler, SchemaDef, SchemaQueries, type SourceChange, SourceConnection, type SourceProvider, Store, StoreProvider, type TTL, type TableMutator, Value, View, buildPipeline, compareValues, evaluate, nodeToRow, parseTTL, tablesOf, unwrapSingular, valuesEqual };
package/dist/client.js ADDED
@@ -0,0 +1,3 @@
1
+ export { IDBKV, MaterializedView, MemoryKV, MemorySource, MemorySourceProvider, Orbit, PROTOCOL_VERSION, Query, QueryManager, SchemaQuery, SourceConnection, Store, StoreProvider, TypedQuery, View, boolean, buildPipeline, buildSchemaQueries, collectOps, compareValues, createBuilder, createSchema, defineMutator, defineQuery, evaluate, hashAST, hashString, json, nodeToRow, number, optional, parseTTL, relationships, string, table, tablesOf, unwrapSingular, valuesEqual } from './chunk-N2NAKHMU.js';
2
+ //# sourceMappingURL=client.js.map
3
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"client.js"}
@@ -0,0 +1,81 @@
1
+ import { R as Row, Q as QueryBuilder, S as Subscribable, C as CrudOp } from './query-BMK1cXAS.js';
2
+ import { S as SchemaDef, R as RowOf, P as PkOf } from './schema-BNM6bks7.js';
3
+
4
+ /** Typed CRUD surface for one table inside a mutator transaction. */
5
+ type TableCRUD<T extends Row, PK extends keyof T> = {
6
+ insert(value: T): void;
7
+ upsert(value: T): void;
8
+ update(value: Pick<T, PK> & Partial<T>): void;
9
+ delete(value: Pick<T, PK>): void;
10
+ };
11
+ /** `tx.mutate.<table>` for every table in the schema. */
12
+ type SchemaCRUD<S extends SchemaDef> = {
13
+ [K in keyof S['tables']]: TableCRUD<RowOf<S['tables'][K]>, PkOf<S['tables'][K]>>;
14
+ };
15
+ /** The transaction passed to a mutator (mirrors Zero's `Transaction`). */
16
+ type Transaction<S extends SchemaDef> = {
17
+ readonly location: 'client';
18
+ readonly mutate: SchemaCRUD<S>;
19
+ };
20
+ /**
21
+ * A mutator's body. Receives a transaction, the client-supplied `args`, and
22
+ * server-supplied `ctx` (the authenticated context — see the push endpoint). A
23
+ * def that doesn't need `ctx` can simply omit it from its destructure.
24
+ */
25
+ type MutatorFn<S extends SchemaDef, Args, Ctx = unknown> = (c: {
26
+ tx: Transaction<S>;
27
+ args: Args;
28
+ ctx: Ctx;
29
+ }) => void | Promise<void>;
30
+ /**
31
+ * A mutator definition. Modeled as the function itself; its args type is inferred
32
+ * from the signature. (`any` in the `tx`/args positions keeps specific defs
33
+ * assignable to the `MutatorDefs` record.)
34
+ */
35
+ type MutatorDef<Args = any> = (c: {
36
+ tx: Transaction<any>;
37
+ args: Args;
38
+ ctx: any;
39
+ }) => void | Promise<void>;
40
+ /** Define a custom mutator (mirrors Zero's `defineMutator`). */
41
+ declare function defineMutator<S extends SchemaDef, Args, Ctx = unknown>(fn: MutatorFn<S, Args, Ctx>): MutatorDef<Args>;
42
+ type MutatorDefs = Record<string, MutatorDef>;
43
+ type ArgsOf<M> = M extends (c: {
44
+ tx: never;
45
+ args: infer A;
46
+ ctx: never;
47
+ }) => unknown ? A : never;
48
+ /** `orbit.mutate` derived from mutator defs — `tx` stripped, args kept. */
49
+ type MutateAPI<MD extends MutatorDefs> = {
50
+ [K in keyof MD]: ArgsOf<MD[K]> extends void | undefined ? () => void : (args: ArgsOf<MD[K]>) => void;
51
+ };
52
+ type QueryFn<Args, Ctx, T extends Row> = (c: {
53
+ args: Args;
54
+ ctx: Ctx;
55
+ }) => QueryBuilder<T>;
56
+ /** A custom query definition (its args + result row types are inferred). */
57
+ type QueryDef<Args = any, T extends Row = Row> = (c: {
58
+ args: Args;
59
+ ctx: any;
60
+ }) => QueryBuilder<T>;
61
+ /** Define a custom (named) query (mirrors Zero's `defineQuery`). */
62
+ declare function defineQuery<T extends Row>(fn: () => QueryBuilder<T>): QueryDef<void, T>;
63
+ declare function defineQuery<Args, Ctx, T extends Row>(fn: QueryFn<Args, Ctx, T>): QueryDef<Args, T>;
64
+ type QueryDefs = Record<string, QueryDef>;
65
+ type QArgsOf<Q> = Q extends (c: {
66
+ args: infer A;
67
+ ctx: never;
68
+ }) => unknown ? A : never;
69
+ type QRowOf<Q> = Q extends (c: never) => Subscribable<infer T> ? T : never;
70
+ /** `orbit.queries` derived from query defs — call with args, get a `Subscribable`. */
71
+ type QueriesAPI<QD extends QueryDefs> = {
72
+ [K in keyof QD]: QArgsOf<QD[K]> extends void | undefined ? () => Subscribable<QRowOf<QD[K]>> : (args: QArgsOf<QD[K]>) => Subscribable<QRowOf<QD[K]>>;
73
+ };
74
+ /**
75
+ * Run a mutator definition against a recording transaction and return the CRUD
76
+ * ops it produced. Use this on **your push endpoint** (the server forwarded the
77
+ * mutation to) to execute a mutator with context, then apply the ops to your DB.
78
+ */
79
+ declare function collectOps<S extends SchemaDef>(schema: S, def: MutatorDef, args: unknown, ctx?: unknown): CrudOp[];
80
+
81
+ export { type MutatorDef as M, type QueryDef as Q, type SchemaCRUD as S, type TableCRUD as T, type MutatorDefs as a, type QueryDefs as b, type QueriesAPI as c, type MutateAPI as d, type Transaction as e, collectOps as f, defineMutator as g, defineQuery as h };
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node
@@ -0,0 +1,51 @@
1
+ #!/usr/bin/env node
2
+ import { generate } from '../../chunk-QR3NSGHJ.js';
3
+ import '../../chunk-2R6QPZNI.js';
4
+ import '../../chunk-7CMFTRDQ.js';
5
+ import '../../chunk-N2NAKHMU.js';
6
+ import * as fs from 'fs';
7
+ import * as path from 'path';
8
+ import { pathToFileURL } from 'url';
9
+ import { Command } from 'commander';
10
+
11
+ var program = new Command();
12
+ program.name("orbit-drizzle").description("Generate an Orbit schema from a Drizzle ORM schema.").argument("[schema]", "path to the Drizzle schema module (overrides config/--schema)").option("-s, --schema <path>", "path to the Drizzle schema module").option("-o, --output <path>", "output file (default ./orbit-schema.gen.ts)").option("-t, --tsconfig <path>", "tsconfig for type resolution").option("-c, --config <path>", "orbit-drizzle config file", "./orbit-drizzle.config.ts").option("-n, --schema-name <name>", "exported schema const name (default schema)").option("--import-from <module>", "module to import Orbit helpers from (default @orbit/client)").option("-f, --format", "format output with Prettier").option("-j, --js-extension", "append .js to relative imports (Node16/NodeNext ESM)").option("--debug", "verbose logging").action(async (schemaArg, opts) => {
13
+ try {
14
+ const fromFile = await loadConfig(opts.config);
15
+ const schemaPath = schemaArg ?? opts.schema ?? fromFile.schemaPath;
16
+ if (!schemaPath) {
17
+ console.error("\u274C orbit-drizzle: no schema given. Pass a path, use --schema, or set `schemaPath` in the config.");
18
+ process.exit(1);
19
+ }
20
+ const options = {
21
+ schemaPath,
22
+ outputPath: opts.output ?? fromFile.outputPath,
23
+ tsConfigPath: opts.tsconfig ?? fromFile.tsConfigPath,
24
+ schemaName: opts.schemaName ?? fromFile.schemaName,
25
+ importFrom: opts.importFrom ?? fromFile.importFrom,
26
+ format: opts.format ?? fromFile.format,
27
+ jsExtension: opts.jsExtension ?? fromFile.jsExtension,
28
+ tables: fromFile.tables,
29
+ debug: opts.debug ?? fromFile.debug
30
+ };
31
+ const { outputPath } = await generate(options);
32
+ console.log(`\u2705 orbit-drizzle: wrote ${path.relative(process.cwd(), outputPath)}`);
33
+ } catch (err) {
34
+ console.error(`\u274C orbit-drizzle: ${err.message}`);
35
+ if (opts.debug) console.error(err);
36
+ process.exit(1);
37
+ }
38
+ });
39
+ async function loadConfig(configPath) {
40
+ if (!configPath) return {};
41
+ const abs = path.resolve(configPath);
42
+ if (!fs.existsSync(abs)) return {};
43
+ const mod = await import(pathToFileURL(abs).href);
44
+ return mod.default ?? {};
45
+ }
46
+ program.parseAsync(process.argv).catch((err) => {
47
+ console.error(err);
48
+ process.exit(1);
49
+ });
50
+ //# sourceMappingURL=bin.js.map
51
+ //# sourceMappingURL=bin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../drizzle/src/cli/bin.ts"],"names":[],"mappings":"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","file":"bin.js","sourcesContent":["#!/usr/bin/env node\n// `orbit-drizzle` CLI. Generates an Orbit schema (`orbit-schema.gen.ts`) from a\n// Drizzle schema, preserving custom `$type<>()` and enum types via the TypeScript\n// compiler. The published bin is plain JS; in-repo, run the source via\n// `node --experimental-strip-types drizzle/src/cli/bin.ts`.\n\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport { Command } from 'commander';\nimport { generate, type GenerateOptions } from './generate.ts';\n\nconst program = new Command();\n\nprogram\n .name('orbit-drizzle')\n .description('Generate an Orbit schema from a Drizzle ORM schema.')\n .argument('[schema]', 'path to the Drizzle schema module (overrides config/--schema)')\n .option('-s, --schema <path>', 'path to the Drizzle schema module')\n .option('-o, --output <path>', 'output file (default ./orbit-schema.gen.ts)')\n .option('-t, --tsconfig <path>', 'tsconfig for type resolution')\n .option('-c, --config <path>', 'orbit-drizzle config file', './orbit-drizzle.config.ts')\n .option('-n, --schema-name <name>', 'exported schema const name (default schema)')\n .option('--import-from <module>', 'module to import Orbit helpers from (default @orbit/client)')\n .option('-f, --format', 'format output with Prettier')\n .option('-j, --js-extension', 'append .js to relative imports (Node16/NodeNext ESM)')\n .option('--debug', 'verbose logging')\n .action(async (schemaArg: string | undefined, opts: Record<string, unknown>) => {\n try {\n const fromFile = await loadConfig(opts.config as string);\n const schemaPath = schemaArg ?? (opts.schema as string | undefined) ?? fromFile.schemaPath;\n if (!schemaPath) {\n console.error('❌ orbit-drizzle: no schema given. Pass a path, use --schema, or set `schemaPath` in the config.');\n process.exit(1);\n }\n // CLI flags win over config; both fall back to generate()'s own defaults.\n const options: GenerateOptions = {\n schemaPath,\n outputPath: (opts.output as string) ?? fromFile.outputPath,\n tsConfigPath: (opts.tsconfig as string) ?? fromFile.tsConfigPath,\n schemaName: (opts.schemaName as string) ?? fromFile.schemaName,\n importFrom: (opts.importFrom as string) ?? fromFile.importFrom,\n format: (opts.format as boolean | undefined) ?? fromFile.format,\n jsExtension: (opts.jsExtension as boolean | undefined) ?? fromFile.jsExtension,\n tables: fromFile.tables,\n debug: (opts.debug as boolean | undefined) ?? fromFile.debug,\n };\n const { outputPath } = await generate(options);\n console.log(`✅ orbit-drizzle: wrote ${path.relative(process.cwd(), outputPath)}`);\n } catch (err) {\n console.error(`❌ orbit-drizzle: ${(err as Error).message}`);\n if (opts.debug) console.error(err);\n process.exit(1);\n }\n });\n\nasync function loadConfig(configPath: string | undefined): Promise<Partial<GenerateOptions>> {\n if (!configPath) return {};\n const abs = path.resolve(configPath);\n if (!fs.existsSync(abs)) return {};\n const mod = (await import(pathToFileURL(abs).href)) as { default?: Partial<GenerateOptions> };\n return mod.default ?? {};\n}\n\nprogram.parseAsync(process.argv).catch((err) => {\n console.error(err);\n process.exit(1);\n});\n"]}
@@ -0,0 +1,63 @@
1
+ import { D as DrizzleAdapterConfig } from '../introspect-zNCdXfuc.js';
2
+ import '../ir-DE_CZz0D.js';
3
+
4
+ interface GenerateOptions {
5
+ /** Path to the Drizzle schema module (a single `.ts` file exporting tables + relations). */
6
+ readonly schemaPath: string;
7
+ /** Output path. Default `./orbit-schema.gen.ts`. */
8
+ readonly outputPath?: string;
9
+ /** tsconfig for type resolution + module resolution. */
10
+ readonly tsConfigPath?: string;
11
+ /** Run Prettier over the output if available. */
12
+ readonly format?: boolean;
13
+ /** Append `.js` to relative imports (Node16/NodeNext ESM). */
14
+ readonly jsExtension?: boolean;
15
+ /** Module the Orbit schema helpers are imported from. Default `@orbit/client`. */
16
+ readonly importFrom?: string;
17
+ /** Exported schema const name. Default `schema`. */
18
+ readonly schemaName?: string;
19
+ /** Table/column selection (see {@link DrizzleAdapterConfig.tables}). */
20
+ readonly tables?: DrizzleAdapterConfig['tables'];
21
+ readonly debug?: boolean;
22
+ }
23
+ interface GenerateResult {
24
+ readonly outputPath: string;
25
+ readonly source: string;
26
+ }
27
+ /** Generate an Orbit schema source file from a Drizzle schema. */
28
+ declare function generate(options: GenerateOptions): Promise<GenerateResult>;
29
+
30
+ interface ResolveColumn {
31
+ readonly jsKey: string;
32
+ readonly dbName: string;
33
+ readonly baseType: 'string' | 'number' | 'boolean' | 'json';
34
+ }
35
+ interface ResolveTable {
36
+ /** The export name of the table in the schema module (e.g. `user`). */
37
+ readonly exportName: string;
38
+ /** The Orbit/database table name. */
39
+ readonly tableName: string;
40
+ readonly columns: readonly ResolveColumn[];
41
+ }
42
+ interface ResolveOptions {
43
+ /** Absolute path to the user's Drizzle schema module. */
44
+ readonly schemaModulePath: string;
45
+ /** Absolute path of the file being generated (for relative import specifiers). */
46
+ readonly outputFilePath: string;
47
+ /** Optional tsconfig for module resolution. */
48
+ readonly tsConfigFilePath?: string;
49
+ /** Append `.js` to emitted relative import specifiers (Node16/NodeNext). */
50
+ readonly jsExtension?: boolean;
51
+ }
52
+ interface ResolvedTypes {
53
+ /** `tableName → dbColumnName → TS type expression`. */
54
+ readonly customTypes: Record<string, Record<string, string>>;
55
+ /** `import type` lines the generated file needs for named custom types. */
56
+ readonly typeImports: {
57
+ module: string;
58
+ names: string[];
59
+ }[];
60
+ }
61
+ declare function resolveCustomTypes(tables: readonly ResolveTable[], options: ResolveOptions): Promise<ResolvedTypes>;
62
+
63
+ export { type GenerateOptions, type GenerateResult, type ResolveColumn, type ResolveTable, type ResolvedTypes, generate, resolveCustomTypes };
@@ -0,0 +1,6 @@
1
+ export { generate, resolveCustomTypes } from '../chunk-QR3NSGHJ.js';
2
+ import '../chunk-2R6QPZNI.js';
3
+ import '../chunk-7CMFTRDQ.js';
4
+ import '../chunk-N2NAKHMU.js';
5
+ //# sourceMappingURL=cli.js.map
6
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"cli.js"}
@@ -0,0 +1,21 @@
1
+ import { S as SchemaIR } from './ir-DE_CZz0D.js';
2
+ import { O as OrmAdapter } from './adapter-C-AhY9cw.js';
3
+ import { S as SchemaDef } from './schema-BNM6bks7.js';
4
+ import { D as DrizzleAdapterConfig } from './introspect-zNCdXfuc.js';
5
+ export { d as drizzleToIR } from './introspect-zNCdXfuc.js';
6
+
7
+ /** The Drizzle → Orbit adapter (implements the ORM-agnostic `OrmAdapter`). */
8
+ declare const drizzleAdapter: OrmAdapter<Record<string, unknown>, DrizzleAdapterConfig>;
9
+ /**
10
+ * Build a live Orbit schema object from a Drizzle schema (runtime path).
11
+ *
12
+ * Returns a generic {@link SchemaDef}: correct at runtime and usable with
13
+ * `createBuilder` / `new Orbit({ schema })`. For a fully-typed schema that
14
+ * preserves `.$type<>()` custom types + enums, use the `orbit-drizzle` CLI (it
15
+ * resolves types with the TypeScript compiler — see the README).
16
+ */
17
+ declare function defineOrbitSchema(schema: Record<string, unknown>, config?: DrizzleAdapterConfig): SchemaDef;
18
+ /** Convert a Drizzle schema directly to the normalized IR (advanced / codegen). */
19
+ declare function drizzleToSchemaIR(schema: Record<string, unknown>, config?: DrizzleAdapterConfig): SchemaIR;
20
+
21
+ export { DrizzleAdapterConfig, defineOrbitSchema, drizzleAdapter, drizzleToSchemaIR };