@radishbot/sdk 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,124 @@
1
+ /**
2
+ * SpacetimeDB connection wrapper for the Radish SDK.
3
+ * Uses the generated bindings + SpacetimeDB WebSocket client.
4
+ */
5
+ import { DbConnection as StdbConnection } from './module_bindings';
6
+
7
+ export class SdkConnection {
8
+ private _host: string;
9
+ private _dbName: string;
10
+ private _conn: StdbConnection | null = null;
11
+ private _connectPromise: Promise<StdbConnection> | null = null;
12
+ private _timeoutInterval: ReturnType<typeof setInterval> | null = null;
13
+ private _keyHash: string | null = null;
14
+
15
+ // Callbacks waiting for flow creation by exportToken
16
+ private _flowWaiters = new Map<string, (id: bigint) => void>();
17
+
18
+ constructor(host: string, dbName: string) {
19
+ this._host = host;
20
+ this._dbName = dbName;
21
+ }
22
+
23
+ setKeyHash(keyHash: string): void {
24
+ this._keyHash = keyHash;
25
+ }
26
+
27
+ async connect(): Promise<StdbConnection> {
28
+ if (this._conn) return this._conn;
29
+ if (this._connectPromise) return this._connectPromise;
30
+
31
+ this._connectPromise = new Promise<StdbConnection>((resolve, reject) => {
32
+ const conn = StdbConnection.builder()
33
+ .withUri(this._host)
34
+ .withDatabaseName(this._dbName)
35
+ .onConnect((c, _identity, _token) => {
36
+ this._conn = c;
37
+
38
+ // Subscribe to flow table to detect newly created flows
39
+ c.subscriptionBuilder()
40
+ .onApplied(() => {
41
+ resolve(c);
42
+ })
43
+ .subscribeToAllTables();
44
+
45
+ // Periodic timeout check (every 30s)
46
+ this._timeoutInterval = setInterval(() => {
47
+ if (this._keyHash) {
48
+ c.reducers.checkTimeouts({ keyHash: this._keyHash });
49
+ }
50
+ }, 30_000);
51
+ })
52
+ .onConnectError((_ctx, err) => {
53
+ reject(new Error(`SpacetimeDB connection failed: ${err}`));
54
+ })
55
+ .build();
56
+ });
57
+
58
+ return this._connectPromise;
59
+ }
60
+
61
+ get conn(): StdbConnection {
62
+ if (!this._conn) throw new Error('Not connected');
63
+ return this._conn;
64
+ }
65
+
66
+ /**
67
+ * Call a reducer and wait for the flow to appear in the subscription.
68
+ * Returns the server-assigned flow ID.
69
+ */
70
+ async createFlowAndResolveId(
71
+ reducerCall: () => void,
72
+ exportToken: string
73
+ ): Promise<bigint> {
74
+ const conn = this.conn;
75
+
76
+ // Check if flow already exists (from a previous subscription update)
77
+ for (const f of conn.db.flow.iter()) {
78
+ if (f.exportToken === exportToken) return f.id;
79
+ }
80
+
81
+ return new Promise<bigint>((resolve) => {
82
+ // Set up watcher
83
+ this._flowWaiters.set(exportToken, resolve);
84
+
85
+ // Call the reducer
86
+ reducerCall();
87
+
88
+ // Also poll in case subscription update was missed
89
+ const check = () => {
90
+ for (const f of conn.db.flow.iter()) {
91
+ if (f.exportToken === exportToken) {
92
+ this._flowWaiters.delete(exportToken);
93
+ resolve(f.id);
94
+ return true;
95
+ }
96
+ }
97
+ return false;
98
+ };
99
+
100
+ // Poll every 100ms for up to 10 seconds
101
+ let attempts = 0;
102
+ const interval = setInterval(() => {
103
+ if (check() || attempts++ > 100) {
104
+ clearInterval(interval);
105
+ if (attempts > 100) {
106
+ this._flowWaiters.delete(exportToken);
107
+ throw new Error(`Flow creation timed out for token ${exportToken}`);
108
+ }
109
+ }
110
+ }, 100);
111
+ });
112
+ }
113
+
114
+ disconnect(): void {
115
+ if (this._timeoutInterval) {
116
+ clearInterval(this._timeoutInterval);
117
+ this._timeoutInterval = null;
118
+ }
119
+ if (this._conn) {
120
+ this._conn.disconnect();
121
+ this._conn = null;
122
+ }
123
+ }
124
+ }
package/src/index.ts ADDED
@@ -0,0 +1,383 @@
1
+ import { SdkConnection } from './connection';
2
+
3
+ export type LogLevel = 'info' | 'warn' | 'error' | 'debug';
4
+
5
+ // ── Console capture ──────────────────────────────────────────
6
+
7
+ const _origConsole = {
8
+ log: console.log,
9
+ info: console.info,
10
+ warn: console.warn,
11
+ error: console.error,
12
+ debug: console.debug,
13
+ };
14
+
15
+ const _flowStack: Flow[] = [];
16
+
17
+ function _patchConsole() {
18
+ const capture = (level: LogLevel) => (...args: unknown[]) => {
19
+ const flow = _flowStack[_flowStack.length - 1];
20
+ if (flow) {
21
+ const msg = args.map(a => {
22
+ if (typeof a === 'string') return a;
23
+ if (a instanceof Error) return a.message;
24
+ try { return JSON.stringify(a); } catch { return String(a); }
25
+ }).join(' ');
26
+ const data = args.length <= 1 ? undefined
27
+ : args.length === 2 ? args[1]
28
+ : args.slice(1);
29
+ flow.log(msg, data, level);
30
+ }
31
+ _origConsole[level === 'info' ? 'log' : level](...args);
32
+ };
33
+ console.log = capture('info');
34
+ console.info = capture('info');
35
+ console.warn = capture('warn');
36
+ console.error = capture('error');
37
+ console.debug = capture('debug');
38
+ }
39
+
40
+ function _restoreConsole() {
41
+ console.log = _origConsole.log;
42
+ console.info = _origConsole.info;
43
+ console.warn = _origConsole.warn;
44
+ console.error = _origConsole.error;
45
+ console.debug = _origConsole.debug;
46
+ }
47
+
48
+ function serialize(value: unknown): string {
49
+ if (value === undefined || value === null) return '{}';
50
+ if (value instanceof Error)
51
+ return JSON.stringify({
52
+ name: value.name,
53
+ message: value.message,
54
+ stack: value.stack,
55
+ });
56
+ try {
57
+ return JSON.stringify(value, (_key, v) =>
58
+ typeof v === 'bigint' ? v.toString() : v
59
+ );
60
+ } catch {
61
+ return JSON.stringify({ value: String(value) });
62
+ }
63
+ }
64
+
65
+ async function hashKey(secretKey: string): Promise<string> {
66
+ const encoder = new TextEncoder();
67
+ const data = encoder.encode(secretKey);
68
+ const hashBuffer = await crypto.subtle.digest('SHA-256', data);
69
+ const hashArray = Array.from(new Uint8Array(hashBuffer));
70
+ return hashArray.map((b) => b.toString(16).padStart(2, '0')).join('');
71
+ }
72
+
73
+ function generateToken(): string {
74
+ const bytes = new Uint8Array(16);
75
+ crypto.getRandomValues(bytes);
76
+ return Array.from(bytes)
77
+ .map((b) => b.toString(16).padStart(2, '0'))
78
+ .join('');
79
+ }
80
+
81
+ export class Flow {
82
+ private _sdk: SdkConnection;
83
+ private _keyHash: string;
84
+ private _id: bigint | null = null;
85
+ private _exportToken: string;
86
+ private _ready: Promise<void>;
87
+ private _resolveReady!: () => void;
88
+ private _pendingLogs: Array<{ level: string; message: string; data: string }> = [];
89
+ private _flushScheduled = false;
90
+ private _isReady = false;
91
+ private _finished = false;
92
+ private _parentId: bigint;
93
+ private _name: string;
94
+ private _timeoutSeconds: bigint;
95
+
96
+ /** @internal */
97
+ constructor(
98
+ sdk: SdkConnection,
99
+ keyHash: string,
100
+ parentId: bigint,
101
+ name: string,
102
+ timeoutSeconds: number
103
+ ) {
104
+ this._sdk = sdk;
105
+ this._keyHash = keyHash;
106
+ this._parentId = parentId;
107
+ this._name = name;
108
+ this._timeoutSeconds = (!timeoutSeconds || timeoutSeconds === Infinity) ? 0n : BigInt(timeoutSeconds);
109
+ this._exportToken = generateToken();
110
+ this._ready = new Promise<void>((resolve) => {
111
+ this._resolveReady = resolve;
112
+ });
113
+ }
114
+
115
+ /** @internal */
116
+ async _create(): Promise<void> {
117
+ const conn = this._sdk.conn;
118
+ const exportToken = this._exportToken;
119
+ const keyHash = this._keyHash;
120
+ const timeoutSeconds = this._timeoutSeconds;
121
+
122
+ if (this._parentId === 0n) {
123
+ const id = await this._sdk.createFlowAndResolveId(
124
+ () => conn.reducers.createRootFlow({ keyHash, timeoutSeconds, exportToken }),
125
+ exportToken
126
+ );
127
+ this._id = id;
128
+ } else {
129
+ const parentFlowId = this._parentId;
130
+ const name = this._name;
131
+ const id = await this._sdk.createFlowAndResolveId(
132
+ () =>
133
+ conn.reducers.createSubFlow({
134
+ keyHash,
135
+ parentFlowId,
136
+ name,
137
+ timeoutSeconds,
138
+ exportToken,
139
+ }),
140
+ exportToken
141
+ );
142
+ this._id = id;
143
+ }
144
+ this._isReady = true;
145
+ this._resolveReady();
146
+ this._drain(); // flush any logs queued before ready
147
+ }
148
+
149
+ /** Log a message with optional data */
150
+ log(message: string, data?: unknown, level: LogLevel = 'info'): this {
151
+ if (this._finished) {
152
+ console.warn(`[radish] Cannot log to finished flow`);
153
+ return this;
154
+ }
155
+ this._pendingLogs.push({
156
+ level,
157
+ message,
158
+ data: data !== undefined ? serialize(data) : '{}',
159
+ });
160
+ this._scheduleFlush();
161
+ return this;
162
+ }
163
+
164
+ info(message: string, data?: unknown): this {
165
+ return this.log(message, data, 'info');
166
+ }
167
+ warn(message: string, data?: unknown): this {
168
+ return this.log(message, data, 'warn');
169
+ }
170
+ error(message: string, data?: unknown): this {
171
+ return this.log(message, data, 'error');
172
+ }
173
+ debug(message: string, data?: unknown): this {
174
+ return this.log(message, data, 'debug');
175
+ }
176
+
177
+ /** Create a sub-action. Returns immediately — creation runs in background. */
178
+ action(name: string, timeoutSeconds = 100): Flow {
179
+ const child = new Flow(this._sdk, this._keyHash, 0n, name, timeoutSeconds);
180
+ this._ready.then(() => {
181
+ (child as any)._parentId = this._id!;
182
+ child._create();
183
+ });
184
+ return child;
185
+ }
186
+
187
+ /** Alias for action() */
188
+ flow(name: string, timeoutSeconds = 100): Flow {
189
+ return this.action(name, timeoutSeconds);
190
+ }
191
+
192
+ /** Run a sub-action — auto-creates, runs fn, auto-finishes. console.* inside fn becomes action logs. */
193
+ async a<T>(name: string, fn: (action: Flow) => T | Promise<T>, timeoutSeconds = 100): Promise<T> {
194
+ const child = this.action(name, timeoutSeconds);
195
+ _flowStack.push(child);
196
+ _patchConsole();
197
+ try {
198
+ const result = await fn(child);
199
+ await child.finish();
200
+ return result;
201
+ } catch (e) {
202
+ await child.finishWithError(e instanceof Error ? e : String(e));
203
+ throw e;
204
+ } finally {
205
+ _flowStack.pop();
206
+ if (_flowStack.length === 0) _restoreConsole();
207
+ }
208
+ }
209
+
210
+ /** Finish this flow successfully */
211
+ async finish(): Promise<void> {
212
+ await this._ready;
213
+ this._drain(); // sync flush — sends over same WS, ordering preserved
214
+ this._finished = true;
215
+ this._sdk.conn.reducers.finishFlow({
216
+ keyHash: this._keyHash,
217
+ flowId: this._id!,
218
+ status: 'finished',
219
+ });
220
+ }
221
+
222
+ /** Finish this flow with error status */
223
+ async finishWithError(err?: Error | string): Promise<void> {
224
+ if (err) {
225
+ this.error(typeof err === 'string' ? err : err.message, err);
226
+ }
227
+ await this._ready;
228
+ this._drain();
229
+ this._finished = true;
230
+ this._sdk.conn.reducers.finishFlow({
231
+ keyHash: this._keyHash,
232
+ flowId: this._id!,
233
+ status: 'error',
234
+ });
235
+ }
236
+
237
+ /** Export this flow's handle for restoration in another context */
238
+ async exportID(): Promise<string> {
239
+ await this._ready;
240
+ return JSON.stringify({
241
+ flowId: this._id!.toString(),
242
+ exportToken: this._exportToken,
243
+ keyHash: this._keyHash,
244
+ });
245
+ }
246
+
247
+ /** Get the resolved server-assigned flow ID */
248
+ async getId(): Promise<bigint> {
249
+ await this._ready;
250
+ return this._id!;
251
+ }
252
+
253
+ /** Schedule a drain on the next microtask — batches sync logs with ~0ms delay */
254
+ private _scheduleFlush() {
255
+ if (this._flushScheduled) return;
256
+ this._flushScheduled = true;
257
+ queueMicrotask(() => {
258
+ this._flushScheduled = false;
259
+ this._drain();
260
+ });
261
+ }
262
+
263
+ /** Synchronously send all pending logs. No-op if flow not ready yet (they'll flush when ready). */
264
+ private _drain(): void {
265
+ if (!this._isReady || this._pendingLogs.length === 0) return;
266
+ const batch = this._pendingLogs.splice(0);
267
+ const conn = this._sdk.conn;
268
+
269
+ if (batch.length === 1) {
270
+ const e = batch[0];
271
+ conn.reducers.addLog({
272
+ keyHash: this._keyHash,
273
+ flowId: this._id!,
274
+ level: e.level,
275
+ message: e.message,
276
+ data: e.data,
277
+ });
278
+ } else {
279
+ conn.reducers.addLogsBatch({
280
+ keyHash: this._keyHash,
281
+ flowId: this._id!,
282
+ entries: JSON.stringify(batch),
283
+ });
284
+ }
285
+ }
286
+ }
287
+
288
+ export interface RLOptions {
289
+ host?: string;
290
+ dbName?: string;
291
+ label?: string;
292
+ defaultTimeout?: number;
293
+ }
294
+
295
+ /**
296
+ * Create a Radish Logger instance. Returns the root action.
297
+ *
298
+ * ```ts
299
+ * const root = await RL('my-secret-key');
300
+ *
301
+ * // Auto-managed — auto-finish on return, auto-error on throw
302
+ * await root.a('request', async (req) => {
303
+ * console.log('GET /api/users');
304
+ * const rows = await req.a('db_query', () => db.query('SELECT ...'));
305
+ * console.log('Done', { count: rows.length });
306
+ * });
307
+ *
308
+ * // Manual — when you need more control
309
+ * const ws = root.action('websocket');
310
+ * ws.info('Connected');
311
+ * await ws.finish();
312
+ *
313
+ * await root.finish();
314
+ * ```
315
+ */
316
+ export async function RL(secretKey: string, options: RLOptions = {}): Promise<Flow> {
317
+ const {
318
+ host = 'wss://maincloud.spacetimedb.com',
319
+ dbName = 'radish-log',
320
+ label = '',
321
+ defaultTimeout = 100,
322
+ } = options;
323
+
324
+ const keyHash = await hashKey(secretKey);
325
+ const sdk = new SdkConnection(host, dbName);
326
+ sdk.setKeyHash(keyHash);
327
+ await sdk.connect();
328
+
329
+ // Register key (idempotent — server rejects dupes)
330
+ try {
331
+ sdk.conn.reducers.registerKey({ keyHash, label });
332
+ } catch {
333
+ // Already registered
334
+ }
335
+
336
+ // Check for timed-out flows (fire-and-forget)
337
+ try {
338
+ sdk.conn.reducers.checkTimeouts({ keyHash });
339
+ } catch {
340
+ // Non-critical
341
+ }
342
+
343
+ // Root flow — creation runs in background, logs queue until ready
344
+ const root = new Flow(sdk, keyHash, 0n, '/', 0);
345
+ root._create(); // fire-and-forget — resolves _ready when server assigns ID
346
+ return root;
347
+ }
348
+
349
+ /** Restore a flow from an exported ID string */
350
+ export async function restoreFlow(
351
+ secretKey: string,
352
+ exportedId: string,
353
+ options: RLOptions = {}
354
+ ): Promise<Flow> {
355
+ const { host = 'wss://maincloud.spacetimedb.com', dbName = 'radish-log' } = options;
356
+
357
+ const parsed = JSON.parse(exportedId);
358
+ const keyHash = await hashKey(secretKey);
359
+ if (keyHash !== parsed.keyHash) {
360
+ throw new Error('Secret key does not match the flow owner');
361
+ }
362
+
363
+ const sdk = new SdkConnection(host, dbName);
364
+ await sdk.connect();
365
+
366
+ const flow = new Flow(sdk, keyHash, 0n, 'restored', 100);
367
+ (flow as any)._id = BigInt(parsed.flowId);
368
+ (flow as any)._exportToken = parsed.exportToken;
369
+ (flow as any)._resolveReady();
370
+ return flow;
371
+ }
372
+
373
+ /** Generate a random secret key */
374
+ export function generateKey(): string {
375
+ const bytes = new Uint8Array(32);
376
+ crypto.getRandomValues(bytes);
377
+ return (
378
+ 'rl_' +
379
+ Array.from(bytes)
380
+ .map((b) => b.toString(16).padStart(2, '0'))
381
+ .join('')
382
+ );
383
+ }
@@ -0,0 +1,20 @@
1
+ // THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
2
+ // WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
3
+
4
+ /* eslint-disable */
5
+ /* tslint:disable */
6
+ import {
7
+ TypeBuilder as __TypeBuilder,
8
+ t as __t,
9
+ type AlgebraicTypeType as __AlgebraicTypeType,
10
+ type Infer as __Infer,
11
+ } from "spacetimedb";
12
+
13
+ export default __t.row({
14
+ id: __t.u64().primaryKey(),
15
+ flowId: __t.u64().name("flow_id"),
16
+ name: __t.string(),
17
+ status: __t.string(),
18
+ createdAt: __t.timestamp().name("created_at"),
19
+ finishedAt: __t.u64().name("finished_at"),
20
+ });
@@ -0,0 +1,19 @@
1
+ // THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
2
+ // WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
3
+
4
+ /* eslint-disable */
5
+ /* tslint:disable */
6
+ import {
7
+ TypeBuilder as __TypeBuilder,
8
+ t as __t,
9
+ type AlgebraicTypeType as __AlgebraicTypeType,
10
+ type Infer as __Infer,
11
+ } from "spacetimedb";
12
+
13
+ export default {
14
+ keyHash: __t.string(),
15
+ flowId: __t.u64(),
16
+ level: __t.string(),
17
+ message: __t.string(),
18
+ data: __t.string(),
19
+ };
@@ -0,0 +1,17 @@
1
+ // THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
2
+ // WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
3
+
4
+ /* eslint-disable */
5
+ /* tslint:disable */
6
+ import {
7
+ TypeBuilder as __TypeBuilder,
8
+ t as __t,
9
+ type AlgebraicTypeType as __AlgebraicTypeType,
10
+ type Infer as __Infer,
11
+ } from "spacetimedb";
12
+
13
+ export default {
14
+ keyHash: __t.string(),
15
+ flowId: __t.u64(),
16
+ entries: __t.string(),
17
+ };
@@ -0,0 +1,17 @@
1
+ // THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
2
+ // WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
3
+
4
+ /* eslint-disable */
5
+ /* tslint:disable */
6
+ import {
7
+ TypeBuilder as __TypeBuilder,
8
+ t as __t,
9
+ type AlgebraicTypeType as __AlgebraicTypeType,
10
+ type Infer as __Infer,
11
+ } from "spacetimedb";
12
+
13
+ export default __t.row({
14
+ keyHash: __t.string().primaryKey().name("key_hash"),
15
+ label: __t.string(),
16
+ createdAt: __t.timestamp().name("created_at"),
17
+ });
@@ -0,0 +1,15 @@
1
+ // THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
2
+ // WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
3
+
4
+ /* eslint-disable */
5
+ /* tslint:disable */
6
+ import {
7
+ TypeBuilder as __TypeBuilder,
8
+ t as __t,
9
+ type AlgebraicTypeType as __AlgebraicTypeType,
10
+ type Infer as __Infer,
11
+ } from "spacetimedb";
12
+
13
+ export default {
14
+ keyHash: __t.string(),
15
+ };
@@ -0,0 +1,17 @@
1
+ // THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
2
+ // WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
3
+
4
+ /* eslint-disable */
5
+ /* tslint:disable */
6
+ import {
7
+ TypeBuilder as __TypeBuilder,
8
+ t as __t,
9
+ type AlgebraicTypeType as __AlgebraicTypeType,
10
+ type Infer as __Infer,
11
+ } from "spacetimedb";
12
+
13
+ export default {
14
+ keyHash: __t.string(),
15
+ timeoutSeconds: __t.u64(),
16
+ exportToken: __t.string(),
17
+ };
@@ -0,0 +1,19 @@
1
+ // THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
2
+ // WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
3
+
4
+ /* eslint-disable */
5
+ /* tslint:disable */
6
+ import {
7
+ TypeBuilder as __TypeBuilder,
8
+ t as __t,
9
+ type AlgebraicTypeType as __AlgebraicTypeType,
10
+ type Infer as __Infer,
11
+ } from "spacetimedb";
12
+
13
+ export default {
14
+ keyHash: __t.string(),
15
+ parentFlowId: __t.u64(),
16
+ name: __t.string(),
17
+ timeoutSeconds: __t.u64(),
18
+ exportToken: __t.string(),
19
+ };
@@ -0,0 +1,17 @@
1
+ // THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
2
+ // WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
3
+
4
+ /* eslint-disable */
5
+ /* tslint:disable */
6
+ import {
7
+ TypeBuilder as __TypeBuilder,
8
+ t as __t,
9
+ type AlgebraicTypeType as __AlgebraicTypeType,
10
+ type Infer as __Infer,
11
+ } from "spacetimedb";
12
+
13
+ export default {
14
+ keyHash: __t.string(),
15
+ actionId: __t.u64(),
16
+ status: __t.string(),
17
+ };
@@ -0,0 +1,17 @@
1
+ // THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
2
+ // WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
3
+
4
+ /* eslint-disable */
5
+ /* tslint:disable */
6
+ import {
7
+ TypeBuilder as __TypeBuilder,
8
+ t as __t,
9
+ type AlgebraicTypeType as __AlgebraicTypeType,
10
+ type Infer as __Infer,
11
+ } from "spacetimedb";
12
+
13
+ export default {
14
+ keyHash: __t.string(),
15
+ flowId: __t.u64(),
16
+ status: __t.string(),
17
+ };
@@ -0,0 +1,24 @@
1
+ // THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
2
+ // WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
3
+
4
+ /* eslint-disable */
5
+ /* tslint:disable */
6
+ import {
7
+ TypeBuilder as __TypeBuilder,
8
+ t as __t,
9
+ type AlgebraicTypeType as __AlgebraicTypeType,
10
+ type Infer as __Infer,
11
+ } from "spacetimedb";
12
+
13
+ export default __t.row({
14
+ id: __t.u64().primaryKey(),
15
+ keyHash: __t.string().name("key_hash"),
16
+ parentFlowId: __t.u64().name("parent_flow_id"),
17
+ name: __t.string(),
18
+ path: __t.string(),
19
+ status: __t.string(),
20
+ timeoutSeconds: __t.u64().name("timeout_seconds"),
21
+ createdAt: __t.timestamp().name("created_at"),
22
+ finishedAt: __t.u64().name("finished_at"),
23
+ exportToken: __t.string().name("export_token"),
24
+ });