@gencow/core 0.1.28 → 0.1.29

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 (65) hide show
  1. package/dist/auth-config.d.ts +92 -5
  2. package/dist/config.d.ts +107 -0
  3. package/dist/config.js +12 -0
  4. package/dist/context.d.ts +139 -0
  5. package/dist/context.js +3 -0
  6. package/dist/crud.d.ts +5 -5
  7. package/dist/crud.js +19 -35
  8. package/dist/document-types.d.ts +2 -2
  9. package/dist/http-action.d.ts +77 -0
  10. package/dist/http-action.js +41 -0
  11. package/dist/index.d.ts +21 -5
  12. package/dist/index.js +12 -3
  13. package/dist/platform-capacity-profile.d.ts +19 -0
  14. package/dist/platform-capacity-profile.js +94 -0
  15. package/dist/procedure.d.ts +58 -0
  16. package/dist/procedure.js +115 -0
  17. package/dist/rag-schema.d.ts +449 -540
  18. package/dist/reactive-mutation-types.d.ts +11 -0
  19. package/dist/reactive-mutation-types.js +1 -0
  20. package/dist/reactive-mutation.d.ts +51 -0
  21. package/dist/reactive-mutation.js +75 -0
  22. package/dist/reactive-query-types.d.ts +12 -0
  23. package/dist/reactive-query-types.js +1 -0
  24. package/dist/reactive-query.d.ts +14 -0
  25. package/dist/reactive-query.js +28 -0
  26. package/dist/reactive-realtime.d.ts +48 -0
  27. package/dist/reactive-realtime.js +236 -0
  28. package/dist/reactive.d.ts +16 -5
  29. package/dist/reactive.js +65 -0
  30. package/dist/runtime-env-policy.js +1 -1
  31. package/dist/server.d.ts +1 -1
  32. package/dist/storage-metering.d.ts +13 -0
  33. package/dist/storage-metering.js +18 -0
  34. package/dist/storage.d.ts +3 -1
  35. package/dist/storage.js +11 -7
  36. package/dist/wake-app-result.d.ts +22 -0
  37. package/dist/wake-app-result.js +11 -0
  38. package/dist/workflow-types.d.ts +13 -1
  39. package/dist/workflow.d.ts +1 -1
  40. package/dist/workflow.js +136 -11
  41. package/dist/workflows-api.js +71 -3
  42. package/package.json +4 -1
  43. package/src/auth-config.ts +104 -3
  44. package/src/config.ts +119 -0
  45. package/src/context.ts +152 -0
  46. package/src/crud.ts +18 -35
  47. package/src/document-types.ts +9 -2
  48. package/src/http-action.ts +101 -0
  49. package/src/index.ts +77 -19
  50. package/src/platform-capacity-profile.ts +114 -0
  51. package/src/procedure.ts +283 -0
  52. package/src/reactive-mutation-types.ts +13 -0
  53. package/src/reactive-mutation.ts +115 -0
  54. package/src/reactive-query-types.ts +14 -0
  55. package/src/reactive-query.ts +48 -0
  56. package/src/reactive-realtime.ts +267 -0
  57. package/src/runtime-env-policy.ts +1 -1
  58. package/src/server.ts +6 -1
  59. package/src/storage-metering.ts +35 -0
  60. package/src/storage.ts +14 -6
  61. package/src/wake-app-result.ts +37 -0
  62. package/src/workflow-types.ts +13 -1
  63. package/src/workflow.ts +166 -12
  64. package/src/workflows-api.ts +82 -3
  65. package/src/reactive.ts +0 -593
@@ -1,5 +1,6 @@
1
1
  import { sql } from "drizzle-orm";
2
- import { mutation, query } from "./reactive.js";
2
+ import { query } from "./reactive-query.js";
3
+ import { mutation } from "./reactive-mutation.js";
3
4
  import {
4
5
  createWorkflowRealtimeToken,
5
6
  deserializeWorkflowValue,
@@ -31,6 +32,7 @@ type WorkflowRow = {
31
32
  current_step: string | null;
32
33
  result: unknown;
33
34
  error: string | null;
35
+ error_code: string | null;
34
36
  retry_count: number;
35
37
  max_retries: number;
36
38
  max_duration_ms: number;
@@ -101,6 +103,7 @@ function mapWorkflowSummary(row: WorkflowRow): WorkflowSummary {
101
103
  derivedStatus: deriveWorkflowStatus(row.status, row.current_step),
102
104
  currentStep: row.current_step,
103
105
  error: row.error,
106
+ errorCode: row.error_code,
104
107
  retryCount: row.retry_count,
105
108
  maxRetries: row.max_retries,
106
109
  maxDurationMs: Number(row.max_duration_ms),
@@ -198,10 +201,77 @@ async function loadWorkflowSignalTarget(
198
201
  FROM _gencow_workflows
199
202
  WHERE id = ${workflowId}
200
203
  LIMIT 1
201
- `);
204
+ `);
202
205
  return rowsFromResult<WorkflowSignalTargetRow>(result)[0] ?? null;
203
206
  }
204
207
 
208
+ function isMissingWorkflowV2SignalSchemaError(error: unknown): boolean {
209
+ const code =
210
+ error && typeof error === "object" && "code" in error ? String((error as { code?: unknown }).code) : "";
211
+ const cause =
212
+ error && typeof error === "object" && "cause" in error ? (error as { cause?: unknown }).cause : null;
213
+ const causeCode =
214
+ cause && typeof cause === "object" && "code" in cause ? String((cause as { code?: unknown }).code) : "";
215
+ const message = error instanceof Error ? error.message : String(error);
216
+ return (
217
+ code === "42P01" ||
218
+ code === "42703" ||
219
+ causeCode === "42P01" ||
220
+ causeCode === "42703" ||
221
+ ((code === "23503" || causeCode === "23503") && message.includes("_gencow_workflow_signals_v2")) ||
222
+ message.includes('relation "_gencow_workflow_signals_v2" does not exist') ||
223
+ message.includes("relation _gencow_workflow_signals_v2 does not exist") ||
224
+ message.includes('relation "_gencow_workflow_runs_v2" does not exist') ||
225
+ message.includes("relation _gencow_workflow_runs_v2 does not exist")
226
+ );
227
+ }
228
+
229
+ async function tryRecordWorkflowV2Signal(options: {
230
+ db: WorkflowDbLike;
231
+ workflowId: string;
232
+ event: string;
233
+ payload: unknown;
234
+ }): Promise<boolean> {
235
+ try {
236
+ await options.db.execute(sql`
237
+ WITH inserted AS (
238
+ INSERT INTO _gencow_workflow_signals_v2 (
239
+ id,
240
+ run_id,
241
+ event_name,
242
+ payload_json,
243
+ idempotency_key
244
+ )
245
+ VALUES (
246
+ ${crypto.randomUUID()},
247
+ ${options.workflowId},
248
+ ${options.event},
249
+ ${JSON.stringify(options.payload)}::jsonb,
250
+ ${crypto.randomUUID()}
251
+ )
252
+ RETURNING run_id
253
+ )
254
+ UPDATE _gencow_workflow_runs_v2 run
255
+ SET
256
+ status = 'queued',
257
+ runnable_at = NOW(),
258
+ lease_owner = NULL,
259
+ lease_expires_at = NULL,
260
+ heartbeat_at = NULL,
261
+ updated_at = NOW()
262
+ FROM inserted
263
+ WHERE run.id = inserted.run_id
264
+ AND run.status = 'waiting'
265
+ AND run.completed_at IS NULL
266
+ AND run.cancel_requested_at IS NULL
267
+ `);
268
+ return true;
269
+ } catch (error) {
270
+ if (isMissingWorkflowV2SignalSchemaError(error)) return false;
271
+ throw error;
272
+ }
273
+ }
274
+
205
275
  export async function loadWorkflowSnapshot(
206
276
  db: WorkflowDbLike,
207
277
  workflowId: string,
@@ -219,6 +289,7 @@ export async function loadWorkflowSnapshot(
219
289
  current_step,
220
290
  result,
221
291
  error,
292
+ error_code,
222
293
  retry_count,
223
294
  max_retries,
224
295
  max_duration_ms,
@@ -326,9 +397,15 @@ export function registerWorkflowsApi(): void {
326
397
  ${crypto.randomUUID()},
327
398
  ${workflow.id},
328
399
  ${normalizedEvent},
329
- ${JSON.stringify(persistedPayload)}::jsonb
400
+ ${JSON.stringify(persistedPayload)}::jsonb
330
401
  )
331
402
  `);
403
+ await tryRecordWorkflowV2Signal({
404
+ db: ctx.unsafeDb,
405
+ workflowId: workflow.id,
406
+ event: normalizedEvent,
407
+ payload: persistedPayload,
408
+ });
332
409
 
333
410
  let scheduledJobId: string | null = null;
334
411
  if (workflow.status === "pending" && workflow.current_step?.startsWith("wait:")) {
@@ -372,6 +449,7 @@ export function registerWorkflowsApi(): void {
372
449
  current_step,
373
450
  result,
374
451
  error,
452
+ error_code,
375
453
  retry_count,
376
454
  max_retries,
377
455
  max_duration_ms,
@@ -393,6 +471,7 @@ export function registerWorkflowsApi(): void {
393
471
  current_step,
394
472
  result,
395
473
  error,
474
+ error_code,
396
475
  retry_count,
397
476
  max_retries,
398
477
  max_duration_ms,