@shware/workflow 0.2.0 → 0.4.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.
- package/README.md +688 -10
- package/dist/client.d.cts +1 -0
- package/dist/client.d.mts +1 -0
- package/dist/cloudflare/bindings.cjs.map +1 -1
- package/dist/cloudflare/bindings.d.cts +11 -0
- package/dist/cloudflare/bindings.d.cts.map +1 -1
- package/dist/cloudflare/bindings.d.mts +11 -0
- package/dist/cloudflare/bindings.d.mts.map +1 -1
- package/dist/cloudflare/bindings.mjs.map +1 -1
- package/dist/cloudflare/index.cjs +1 -0
- package/dist/cloudflare/index.d.cts +3 -3
- package/dist/cloudflare/index.d.mts +3 -3
- package/dist/cloudflare/index.mjs +2 -2
- package/dist/cloudflare/router.cjs +21 -4
- package/dist/cloudflare/router.cjs.map +1 -1
- package/dist/cloudflare/router.d.cts +18 -3
- package/dist/cloudflare/router.d.cts.map +1 -1
- package/dist/cloudflare/router.d.mts +18 -3
- package/dist/cloudflare/router.d.mts.map +1 -1
- package/dist/cloudflare/router.mjs +21 -5
- package/dist/cloudflare/router.mjs.map +1 -1
- package/dist/cloudflare/worker.cjs +37 -1
- package/dist/cloudflare/worker.cjs.map +1 -1
- package/dist/cloudflare/worker.d.cts.map +1 -1
- package/dist/cloudflare/worker.d.mts.map +1 -1
- package/dist/cloudflare/worker.mjs +37 -1
- package/dist/cloudflare/worker.mjs.map +1 -1
- package/dist/contract.d.cts +1 -0
- package/dist/contract.d.mts +1 -0
- package/dist/dsl/condition.d.cts +1 -0
- package/dist/dsl/condition.d.mts +1 -0
- package/dist/dsl/flow.d.cts +1 -0
- package/dist/dsl/flow.d.mts +1 -0
- package/dist/dsl/template.d.cts +1 -0
- package/dist/dsl/template.d.mts +1 -0
- package/dist/ir.d.cts +1 -0
- package/dist/ir.d.mts +1 -0
- package/dist/provenance.d.cts +1 -0
- package/dist/provenance.d.mts +1 -0
- package/dist/store/index.cjs.map +1 -1
- package/dist/store/index.d.cts +21 -0
- package/dist/store/index.d.cts.map +1 -1
- package/dist/store/index.d.mts +21 -0
- package/dist/store/index.d.mts.map +1 -1
- package/dist/store/index.mjs.map +1 -1
- package/dist/store/postgres.cjs +45 -20
- package/dist/store/postgres.cjs.map +1 -1
- package/dist/store/postgres.d.cts +4 -1
- package/dist/store/postgres.d.cts.map +1 -1
- package/dist/store/postgres.d.mts +4 -1
- package/dist/store/postgres.d.mts.map +1 -1
- package/dist/store/postgres.mjs +45 -20
- package/dist/store/postgres.mjs.map +1 -1
- package/dist/store/tables.cjs +11 -0
- package/dist/store/tables.cjs.map +1 -1
- package/dist/store/tables.d.cts +1 -0
- package/dist/store/tables.d.cts.map +1 -1
- package/dist/store/tables.d.mts +1 -0
- package/dist/store/tables.d.mts.map +1 -1
- package/dist/store/tables.mjs +11 -0
- package/dist/store/tables.mjs.map +1 -1
- package/dist/templates.d.cts +1 -0
- package/dist/templates.d.mts +1 -0
- package/dist/webpush.d.cts +1 -0
- package/dist/webpush.d.mts +1 -0
- package/package.json +13 -12
package/dist/store/tables.mjs
CHANGED
|
@@ -169,6 +169,17 @@ const TABLES = {
|
|
|
169
169
|
primaryKey: ["wakeHandle", "event"],
|
|
170
170
|
indexes: [["userId", "event"]]
|
|
171
171
|
}),
|
|
172
|
+
deployment: table({
|
|
173
|
+
name: "deployment",
|
|
174
|
+
doc: "The Worker version whose compiled bundle the routes came from, one row (`scope` = 'routes'): journeyWorker applies its own bundle only over an older version, so one still serving during a rollout cannot put its routes back. A forced `POST /bundle/deploy` leaves it as it is.",
|
|
175
|
+
columns: {
|
|
176
|
+
scope: text,
|
|
177
|
+
versionId: text,
|
|
178
|
+
versionCreatedAt: ts,
|
|
179
|
+
appliedAt: ts
|
|
180
|
+
},
|
|
181
|
+
primaryKey: ["scope"]
|
|
182
|
+
}),
|
|
172
183
|
ir: table({
|
|
173
184
|
name: "ir",
|
|
174
185
|
doc: "Workflow bodies (WorkflowIR), content-addressed.",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tables.mjs","names":[],"sources":["../../src/store/tables.ts"],"sourcesContent":["/**\n * The engine's Postgres tables, declared once. Everything that needs their shape derives it from\n * here: the drizzle schema file a host generates and migrates with its own tooling\n * (`renderDrizzleSchema`), the plain DDL (`renderPostgresDdl`), the store's table names, and the\n * check a deploy runs against the live database (`checkPostgresSchema`).\n *\n * The house rules hold for every table: no database defaults (the store writes every value,\n * timestamps included), timestamptz for time, and a UUID v7 row id — generated by the store and\n * guarded by a CHECK — wherever a table has a surrogate key. All tables live in one Postgres\n * schema of their own (`workflow` unless the config names another), so their short names never\n * meet the app's.\n */\n\nexport type ColumnType = 'uuid' | 'text' | 'jsonb' | 'timestamptz' | 'integer' | 'boolean';\n\nexport interface ColumnSpec {\n type: ColumnType;\n /** Columns are NOT NULL unless marked. */\n nullable?: boolean;\n /** One line for the generated file. */\n doc?: string;\n}\n\nexport interface TableSpec<K extends string = string> {\n /** Physical table name inside the schema. */\n name: string;\n doc: string;\n /** Keyed by the drizzle property name; the column name is its snake_case. */\n columns: Record<K, ColumnSpec>;\n primaryKey: readonly K[];\n /** A uuid column whose values must be version 7. */\n uuidV7?: K;\n uniqueIndexes?: readonly (readonly K[])[];\n indexes?: readonly (readonly K[])[];\n /** Foreign keys, to another table's logical key. */\n references?: readonly {\n columns: readonly K[];\n table: string;\n foreignColumns: readonly string[];\n }[];\n}\n\nfunction table<K extends string>(spec: TableSpec<K>): TableSpec<K> {\n return spec;\n}\n\nconst uuid = { type: 'uuid' } as const;\nconst text = { type: 'text' } as const;\nconst jsonb = { type: 'jsonb' } as const;\nconst ts = { type: 'timestamptz' } as const;\nconst integer = { type: 'integer' } as const;\nconst boolean = { type: 'boolean' } as const;\nconst nullable = <C extends ColumnSpec>(column: C, doc?: string): ColumnSpec => ({\n ...column,\n nullable: true,\n ...(doc === undefined ? {} : { doc }),\n});\n\nexport const TABLES = {\n event: table({\n name: 'event',\n doc: \"Every ingested event, the fact base for `performed(...)` conditions. `event_id` is the occurrence's identity as the sender chose it (a retrying producer sends the same one again); its unique index makes a second delivery a no-op.\",\n columns: { id: uuid, eventId: text, userId: text, name: text, ts, payload: jsonb },\n primaryKey: ['id'],\n uuidV7: 'id',\n uniqueIndexes: [['eventId']],\n indexes: [['userId', 'name', 'ts']],\n }),\n profile: table({\n name: 'profile',\n doc: 'Identified properties per user (`/identify` merges into `props`; a null value means unset).',\n columns: { userId: text, props: jsonb },\n primaryKey: ['userId'],\n }),\n device: table({\n name: 'device',\n doc: 'Push devices, registered through the Worker (`JourneyClient.registerDevice`). Signing out unbinds a device (`user_id` null) rather than removing it; a token APNs / FCM reports as gone is removed.',\n columns: { token: text, userId: nullable(text), platform: text, ts },\n primaryKey: ['token'],\n indexes: [['userId']],\n }),\n erasure: table({\n name: 'erasure',\n doc: \"Erasures in progress (`forgetUser`): the user's data stays until every running instance is stopped, and the scheduled sweep retries what is left.\",\n columns: { userId: text, requestedAt: ts },\n primaryKey: ['userId'],\n }),\n suppression: table({\n name: 'suppression',\n doc: 'Channels a user opted out of (an email unsubscribe): the engine sends nothing there, and `reachable(channel)` is false.',\n columns: { userId: text, channel: text, ts },\n primaryKey: ['userId', 'channel'],\n }),\n segment: table({\n name: 'segment',\n doc: 'Deployed segment definitions, resolved by name at evaluation time.',\n columns: { id: text, condition: jsonb, hash: text },\n primaryKey: ['id'],\n }),\n trigger: table({\n name: 'trigger',\n doc: 'Event-trigger routes: `where` gates on the event payload, `filter` on the profile.',\n columns: {\n workflow: text,\n hash: text,\n event: text,\n where: nullable(jsonb),\n filter: nullable(jsonb),\n },\n primaryKey: ['workflow'],\n indexes: [['event']],\n }),\n segmentTrigger: table({\n name: 'segment_trigger',\n doc: 'Segment-entry trigger routes.',\n columns: { workflow: text, hash: text, segment: text },\n primaryKey: ['workflow'],\n indexes: [['segment']],\n }),\n segmentMember: table({\n name: 'segment_member',\n doc: 'Who is in each deployed segment and since when: kept by the scheduled sweep, and for trigger-routed segments on every event too.',\n columns: { segment: text, userId: text, ts },\n primaryKey: ['segment', 'userId'],\n }),\n segmentStart: table({\n name: 'segment_start',\n doc: 'Workflows a segment entry still has to start for a member: written with the membership, removed as each one starts, so a failed start is retried by the next evaluation instead of being hidden behind the membership.',\n columns: { segment: text, workflow: text, userId: text, ts },\n primaryKey: ['segment', 'workflow', 'userId'],\n }),\n segmentSnapshot: table({\n name: 'segment_snapshot',\n doc: \"Each segment's size at every sweep, the Studio's sparklines.\",\n columns: { segment: text, takenAt: ts, size: integer },\n primaryKey: ['segment', 'takenAt'],\n }),\n entry: table({\n name: 'entry',\n doc: 'Entry ledger: the (workflow, user) primary key is the once policy.',\n columns: { workflow: text, userId: text, instanceId: text, hash: text, status: text, ts },\n primaryKey: ['workflow', 'userId'],\n indexes: [['instanceId']],\n }),\n subscription: table({\n name: 'subscription',\n doc: 'wait_until wake routing; the primary key makes repeated subscribes idempotent.',\n columns: { userId: text, event: text, wakeHandle: text, ts },\n primaryKey: ['wakeHandle', 'event'],\n indexes: [['userId', 'event']],\n }),\n ir: table({\n name: 'ir',\n doc: 'Workflow bodies (WorkflowIR), content-addressed.',\n columns: { contentHash: text, ir: jsonb },\n primaryKey: ['contentHash'],\n }),\n instance: table({\n name: 'instance',\n doc: 'One row per journey instance, written when it enters: the node it sits on or last passed (none when a guard ended it before the first), and how it ended (`running` until then; `goal` is a conversion, at `finished_at`).',\n columns: {\n instanceId: text,\n workflow: text,\n userId: text,\n enteredAt: ts,\n nodeId: nullable(text),\n nodeAt: nullable(ts),\n status: text,\n finishedAt: nullable(ts),\n convertedAt: nullable(\n ts,\n 'When the goal was met, whatever the status: with `exitOnMatch: false` a converted instance ends `completed`.'\n ),\n },\n primaryKey: ['instanceId'],\n indexes: [\n ['workflow', 'status'],\n ['workflow', 'finishedAt'],\n ],\n }),\n message: table({\n name: 'message',\n doc: \"One row per message copy (a push fans out per device). The idempotency key is the engine's copy identity, so a retried step finds the row it wrote; `channel` is where the copy landed (`email`, `push_ios`, `push_android`).\",\n columns: {\n id: uuid,\n idempotencyKey: text,\n workflow: text,\n instanceId: text,\n nodeId: text,\n template: text,\n channel: text,\n userId: text,\n sentAt: ts,\n deliveredAt: nullable(ts, 'The transport accepted it.'),\n deviceDeliveredAt: nullable(\n ts,\n \"A push: the device reported it received (iOS's notification service extension, a browser's service worker).\"\n ),\n undeliveredReason: nullable(\n text,\n 'The transport settled it without delivering (a dead push token).'\n ),\n openedAt: nullable(ts, 'First open of any kind, by a person or a machine.'),\n humanOpenedAt: nullable(ts, 'First open a person made.'),\n clickedAt: nullable(ts),\n humanClickedAt: nullable(ts),\n unsubscribedAt: nullable(ts),\n },\n primaryKey: ['id'],\n uuidV7: 'id',\n uniqueIndexes: [['idempotencyKey']],\n indexes: [['workflow', 'sentAt'], ['instanceId']],\n }),\n messageLink: table({\n name: 'message_link',\n doc: \"A sent email's links in document order: the tracked URL names a message and a position, and the redirect goes only to the URL recorded here.\",\n columns: { messageId: uuid, position: integer, url: text },\n primaryKey: ['messageId', 'position'],\n references: [{ columns: ['messageId'], table: 'message', foreignColumns: ['id'] }],\n }),\n messageOpen: table({\n name: 'message_open',\n doc: \"Every open-pixel load or push tap, classified when recorded: `machine` when no person caused it, with the deciding rule in `reason`; the request's network (never its address) kept for revisiting the rules.\",\n columns: {\n id: uuid,\n messageId: uuid,\n openedAt: ts,\n machine: boolean,\n reason: nullable(text),\n userAgent: nullable(text),\n asn: nullable(integer),\n asOrganization: nullable(text),\n country: nullable(text),\n },\n primaryKey: ['id'],\n uuidV7: 'id',\n indexes: [['messageId']],\n references: [{ columns: ['messageId'], table: 'message', foreignColumns: ['id'] }],\n }),\n messageClick: table({\n name: 'message_click',\n doc: 'Every click on a tracked link, classified like opens.',\n columns: {\n id: uuid,\n messageId: uuid,\n position: integer,\n url: text,\n clickedAt: ts,\n machine: boolean,\n reason: nullable(text),\n userAgent: nullable(text),\n asn: nullable(integer),\n asOrganization: nullable(text),\n country: nullable(text),\n },\n primaryKey: ['id'],\n uuidV7: 'id',\n indexes: [['messageId']],\n references: [{ columns: ['messageId'], table: 'message', foreignColumns: ['id'] }],\n }),\n} satisfies Record<string, TableSpec>;\n\nexport type TableKey = keyof typeof TABLES;\n\n/** The engine's schema when the config names none. */\nexport const DEFAULT_SCHEMA = 'workflow';\n\n/** `eventId` → `event_id`. */\nexport function columnName(key: string): string {\n return key.replace(/[A-Z]/g, (c) => `_${c.toLowerCase()}`);\n}\n\nconst quote = (name: string) => `\"${name.replace(/\"/g, '\"\"')}\"`;\n\nconst SQL_TYPES: Record<ColumnType, string> = {\n uuid: 'uuid',\n text: 'text',\n jsonb: 'jsonb',\n timestamptz: 'timestamptz',\n integer: 'integer',\n boolean: 'boolean',\n};\n\n/**\n * Plain Postgres DDL for every table — for a host without a migration tool, and the tests. A\n * host that migrates with drizzle generates `renderDrizzleSchema` instead and lets drizzle-kit\n * write the migration.\n */\nexport function renderPostgresDdl(schema = DEFAULT_SCHEMA): string {\n const s = quote(schema);\n const out = [`CREATE SCHEMA IF NOT EXISTS ${s};`];\n for (const spec of Object.values(TABLES)) {\n const lines = Object.entries(spec.columns).map(\n ([key, column]) =>\n ` ${quote(columnName(key))} ${SQL_TYPES[column.type]}${column.nullable ? '' : ' NOT NULL'}`\n );\n lines.push(` PRIMARY KEY (${spec.primaryKey.map((k) => quote(columnName(k))).join(', ')})`);\n if (spec.uuidV7 !== undefined) {\n lines.push(\n ` CONSTRAINT ${quote(`${spec.name}_uuid_v7`)} CHECK (substring(${quote(columnName(spec.uuidV7))}::text, 15, 1) = '7')`\n );\n }\n for (const ref of spec.references ?? []) {\n const target = TABLES[ref.table as TableKey];\n lines.push(\n ` FOREIGN KEY (${ref.columns.map((k) => quote(columnName(k))).join(', ')}) REFERENCES ${s}.${quote(target.name)} (${ref.foreignColumns.map((k) => quote(columnName(k))).join(', ')})`\n );\n }\n out.push(`CREATE TABLE IF NOT EXISTS ${s}.${quote(spec.name)} (\\n${lines.join(',\\n')}\\n);`);\n const index = (unique: boolean) => (keys: readonly string[]) => {\n const cols = keys.map(columnName);\n out.push(\n `CREATE ${unique ? 'UNIQUE ' : ''}INDEX IF NOT EXISTS ${quote(`${spec.name}_${cols.join('_')}_index`)} ON ${s}.${quote(spec.name)} (${cols.map(quote).join(', ')});`\n );\n };\n (spec.uniqueIndexes ?? []).forEach(index(true));\n (spec.indexes ?? []).forEach(index(false));\n }\n return `${out.join('\\n')}\\n`;\n}\n\nconst DRIZZLE_TYPES: Record<ColumnType, (column: string) => string> = {\n uuid: (c) => `uuid('${c}')`,\n text: (c) => `text('${c}')`,\n jsonb: (c) => `jsonb('${c}')`,\n timestamptz: (c) => `timestamp('${c}', { mode: 'string', withTimezone: true })`,\n integer: (c) => `integer('${c}')`,\n boolean: (c) => `boolean('${c}')`,\n};\n\nconst exportName = (key: string) => `workflow${key.charAt(0).toUpperCase()}${key.slice(1)}`;\n\n/**\n * The tables as one drizzle file: `export const workflowSchema = pgSchema(<schema>)` and every\n * table as `workflowSchema.table(...)`. The host re-exports it from its drizzle schema and\n * generates the migration with drizzle-kit, so the migration history stays the host's. The\n * output is deterministic — regenerate and diff it in CI to catch an SDK upgrade that changed the\n * tables.\n */\nexport function renderDrizzleSchema(schema = DEFAULT_SCHEMA): string {\n const specs = Object.entries(TABLES) as [TableKey, TableSpec][];\n const used = new Set<string>(['pgSchema']);\n const body: string[] = [];\n let needsSql = false;\n for (const [key, spec] of specs) {\n const columns = Object.entries(spec.columns).map(([prop, column]) => {\n used.add(column.type === 'timestamptz' ? 'timestamp' : column.type);\n const doc = column.doc === undefined ? '' : ` /** ${column.doc} */\\n`;\n const key =\n spec.primaryKey.length === 1 && spec.primaryKey[0] === prop ? '.primaryKey()' : '';\n return `${doc} ${prop}: ${DRIZZLE_TYPES[column.type](columnName(prop))}${key}${column.nullable ? '' : '.notNull()'},`;\n });\n const extras: string[] = [];\n if (spec.primaryKey.length > 1) {\n used.add('primaryKey');\n extras.push(\n `primaryKey({ columns: [${spec.primaryKey.map((k) => `table.${k}`).join(', ')}] })`\n );\n }\n for (const keys of spec.uniqueIndexes ?? []) {\n used.add('uniqueIndex');\n extras.push(`uniqueIndex().on(${keys.map((k) => `table.${k}`).join(', ')})`);\n }\n for (const keys of spec.indexes ?? []) {\n used.add('index');\n extras.push(`index().on(${keys.map((k) => `table.${k}`).join(', ')})`);\n }\n for (const ref of spec.references ?? []) {\n used.add('foreignKey');\n extras.push(\n `foreignKey({ columns: [${ref.columns.map((k) => `table.${k}`).join(', ')}], foreignColumns: [${ref.foreignColumns.map((k) => `${exportName(ref.table)}.${k}`).join(', ')}] })`\n );\n }\n if (spec.uuidV7 !== undefined) {\n used.add('check');\n needsSql = true;\n extras.push(\n `check('${spec.name}_uuid_v7', sql\\`substring(\\${table.${spec.uuidV7}}::text, 15, 1) = '7'\\`)`\n );\n }\n const third =\n extras.length === 0\n ? ''\n : `,\\n (table) => [\\n${extras.map((e) => ` ${e},`).join('\\n')}\\n ]`;\n body.push(\n `/** ${spec.doc} */\\nexport const ${exportName(key)} = workflowSchema.table(\\n '${spec.name}',\\n {\\n${columns.join('\\n')}\\n }${third}\\n);`\n );\n }\n const imports = [...used].sort();\n return [\n '// Generated by `workflow-ui generate` from @shware/workflow — do not edit; regenerate after',\n '// upgrading the SDK and let drizzle-kit write the migration.',\n ...(needsSql ? [\"import { sql } from 'drizzle-orm';\"] : []),\n `import {\\n${imports.map((name) => ` ${name},`).join('\\n')}\\n} from 'drizzle-orm/pg-core';`,\n '',\n `export const workflowSchema = pgSchema('${schema}');`,\n '',\n body.join('\\n\\n'),\n '',\n ].join('\\n');\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"tables.mjs","names":[],"sources":["../../src/store/tables.ts"],"sourcesContent":["/**\n * The engine's Postgres tables, declared once. Everything that needs their shape derives it from\n * here: the drizzle schema file a host generates and migrates with its own tooling\n * (`renderDrizzleSchema`), the plain DDL (`renderPostgresDdl`), the store's table names, and the\n * check a deploy runs against the live database (`checkPostgresSchema`).\n *\n * The house rules hold for every table: no database defaults (the store writes every value,\n * timestamps included), timestamptz for time, and a UUID v7 row id — generated by the store and\n * guarded by a CHECK — wherever a table has a surrogate key. All tables live in one Postgres\n * schema of their own (`workflow` unless the config names another), so their short names never\n * meet the app's.\n */\n\nexport type ColumnType = 'uuid' | 'text' | 'jsonb' | 'timestamptz' | 'integer' | 'boolean';\n\nexport interface ColumnSpec {\n type: ColumnType;\n /** Columns are NOT NULL unless marked. */\n nullable?: boolean;\n /** One line for the generated file. */\n doc?: string;\n}\n\nexport interface TableSpec<K extends string = string> {\n /** Physical table name inside the schema. */\n name: string;\n doc: string;\n /** Keyed by the drizzle property name; the column name is its snake_case. */\n columns: Record<K, ColumnSpec>;\n primaryKey: readonly K[];\n /** A uuid column whose values must be version 7. */\n uuidV7?: K;\n uniqueIndexes?: readonly (readonly K[])[];\n indexes?: readonly (readonly K[])[];\n /** Foreign keys, to another table's logical key. */\n references?: readonly {\n columns: readonly K[];\n table: string;\n foreignColumns: readonly string[];\n }[];\n}\n\nfunction table<K extends string>(spec: TableSpec<K>): TableSpec<K> {\n return spec;\n}\n\nconst uuid = { type: 'uuid' } as const;\nconst text = { type: 'text' } as const;\nconst jsonb = { type: 'jsonb' } as const;\nconst ts = { type: 'timestamptz' } as const;\nconst integer = { type: 'integer' } as const;\nconst boolean = { type: 'boolean' } as const;\nconst nullable = <C extends ColumnSpec>(column: C, doc?: string): ColumnSpec => ({\n ...column,\n nullable: true,\n ...(doc === undefined ? {} : { doc }),\n});\n\nexport const TABLES = {\n event: table({\n name: 'event',\n doc: \"Every ingested event, the fact base for `performed(...)` conditions. `event_id` is the occurrence's identity as the sender chose it (a retrying producer sends the same one again); its unique index makes a second delivery a no-op.\",\n columns: { id: uuid, eventId: text, userId: text, name: text, ts, payload: jsonb },\n primaryKey: ['id'],\n uuidV7: 'id',\n uniqueIndexes: [['eventId']],\n indexes: [['userId', 'name', 'ts']],\n }),\n profile: table({\n name: 'profile',\n doc: 'Identified properties per user (`/identify` merges into `props`; a null value means unset).',\n columns: { userId: text, props: jsonb },\n primaryKey: ['userId'],\n }),\n device: table({\n name: 'device',\n doc: 'Push devices, registered through the Worker (`JourneyClient.registerDevice`). Signing out unbinds a device (`user_id` null) rather than removing it; a token APNs / FCM reports as gone is removed.',\n columns: { token: text, userId: nullable(text), platform: text, ts },\n primaryKey: ['token'],\n indexes: [['userId']],\n }),\n erasure: table({\n name: 'erasure',\n doc: \"Erasures in progress (`forgetUser`): the user's data stays until every running instance is stopped, and the scheduled sweep retries what is left.\",\n columns: { userId: text, requestedAt: ts },\n primaryKey: ['userId'],\n }),\n suppression: table({\n name: 'suppression',\n doc: 'Channels a user opted out of (an email unsubscribe): the engine sends nothing there, and `reachable(channel)` is false.',\n columns: { userId: text, channel: text, ts },\n primaryKey: ['userId', 'channel'],\n }),\n segment: table({\n name: 'segment',\n doc: 'Deployed segment definitions, resolved by name at evaluation time.',\n columns: { id: text, condition: jsonb, hash: text },\n primaryKey: ['id'],\n }),\n trigger: table({\n name: 'trigger',\n doc: 'Event-trigger routes: `where` gates on the event payload, `filter` on the profile.',\n columns: {\n workflow: text,\n hash: text,\n event: text,\n where: nullable(jsonb),\n filter: nullable(jsonb),\n },\n primaryKey: ['workflow'],\n indexes: [['event']],\n }),\n segmentTrigger: table({\n name: 'segment_trigger',\n doc: 'Segment-entry trigger routes.',\n columns: { workflow: text, hash: text, segment: text },\n primaryKey: ['workflow'],\n indexes: [['segment']],\n }),\n segmentMember: table({\n name: 'segment_member',\n doc: 'Who is in each deployed segment and since when: kept by the scheduled sweep, and for trigger-routed segments on every event too.',\n columns: { segment: text, userId: text, ts },\n primaryKey: ['segment', 'userId'],\n }),\n segmentStart: table({\n name: 'segment_start',\n doc: 'Workflows a segment entry still has to start for a member: written with the membership, removed as each one starts, so a failed start is retried by the next evaluation instead of being hidden behind the membership.',\n columns: { segment: text, workflow: text, userId: text, ts },\n primaryKey: ['segment', 'workflow', 'userId'],\n }),\n segmentSnapshot: table({\n name: 'segment_snapshot',\n doc: \"Each segment's size at every sweep, the Studio's sparklines.\",\n columns: { segment: text, takenAt: ts, size: integer },\n primaryKey: ['segment', 'takenAt'],\n }),\n entry: table({\n name: 'entry',\n doc: 'Entry ledger: the (workflow, user) primary key is the once policy.',\n columns: { workflow: text, userId: text, instanceId: text, hash: text, status: text, ts },\n primaryKey: ['workflow', 'userId'],\n indexes: [['instanceId']],\n }),\n subscription: table({\n name: 'subscription',\n doc: 'wait_until wake routing; the primary key makes repeated subscribes idempotent.',\n columns: { userId: text, event: text, wakeHandle: text, ts },\n primaryKey: ['wakeHandle', 'event'],\n indexes: [['userId', 'event']],\n }),\n deployment: table({\n name: 'deployment',\n doc: \"The Worker version whose compiled bundle the routes came from, one row (`scope` = 'routes'): journeyWorker applies its own bundle only over an older version, so one still serving during a rollout cannot put its routes back. A forced `POST /bundle/deploy` leaves it as it is.\",\n columns: { scope: text, versionId: text, versionCreatedAt: ts, appliedAt: ts },\n primaryKey: ['scope'],\n }),\n ir: table({\n name: 'ir',\n doc: 'Workflow bodies (WorkflowIR), content-addressed.',\n columns: { contentHash: text, ir: jsonb },\n primaryKey: ['contentHash'],\n }),\n instance: table({\n name: 'instance',\n doc: 'One row per journey instance, written when it enters: the node it sits on or last passed (none when a guard ended it before the first), and how it ended (`running` until then; `goal` is a conversion, at `finished_at`).',\n columns: {\n instanceId: text,\n workflow: text,\n userId: text,\n enteredAt: ts,\n nodeId: nullable(text),\n nodeAt: nullable(ts),\n status: text,\n finishedAt: nullable(ts),\n convertedAt: nullable(\n ts,\n 'When the goal was met, whatever the status: with `exitOnMatch: false` a converted instance ends `completed`.'\n ),\n },\n primaryKey: ['instanceId'],\n indexes: [\n ['workflow', 'status'],\n ['workflow', 'finishedAt'],\n ],\n }),\n message: table({\n name: 'message',\n doc: \"One row per message copy (a push fans out per device). The idempotency key is the engine's copy identity, so a retried step finds the row it wrote; `channel` is where the copy landed (`email`, `push_ios`, `push_android`).\",\n columns: {\n id: uuid,\n idempotencyKey: text,\n workflow: text,\n instanceId: text,\n nodeId: text,\n template: text,\n channel: text,\n userId: text,\n sentAt: ts,\n deliveredAt: nullable(ts, 'The transport accepted it.'),\n deviceDeliveredAt: nullable(\n ts,\n \"A push: the device reported it received (iOS's notification service extension, a browser's service worker).\"\n ),\n undeliveredReason: nullable(\n text,\n 'The transport settled it without delivering (a dead push token).'\n ),\n openedAt: nullable(ts, 'First open of any kind, by a person or a machine.'),\n humanOpenedAt: nullable(ts, 'First open a person made.'),\n clickedAt: nullable(ts),\n humanClickedAt: nullable(ts),\n unsubscribedAt: nullable(ts),\n },\n primaryKey: ['id'],\n uuidV7: 'id',\n uniqueIndexes: [['idempotencyKey']],\n indexes: [['workflow', 'sentAt'], ['instanceId']],\n }),\n messageLink: table({\n name: 'message_link',\n doc: \"A sent email's links in document order: the tracked URL names a message and a position, and the redirect goes only to the URL recorded here.\",\n columns: { messageId: uuid, position: integer, url: text },\n primaryKey: ['messageId', 'position'],\n references: [{ columns: ['messageId'], table: 'message', foreignColumns: ['id'] }],\n }),\n messageOpen: table({\n name: 'message_open',\n doc: \"Every open-pixel load or push tap, classified when recorded: `machine` when no person caused it, with the deciding rule in `reason`; the request's network (never its address) kept for revisiting the rules.\",\n columns: {\n id: uuid,\n messageId: uuid,\n openedAt: ts,\n machine: boolean,\n reason: nullable(text),\n userAgent: nullable(text),\n asn: nullable(integer),\n asOrganization: nullable(text),\n country: nullable(text),\n },\n primaryKey: ['id'],\n uuidV7: 'id',\n indexes: [['messageId']],\n references: [{ columns: ['messageId'], table: 'message', foreignColumns: ['id'] }],\n }),\n messageClick: table({\n name: 'message_click',\n doc: 'Every click on a tracked link, classified like opens.',\n columns: {\n id: uuid,\n messageId: uuid,\n position: integer,\n url: text,\n clickedAt: ts,\n machine: boolean,\n reason: nullable(text),\n userAgent: nullable(text),\n asn: nullable(integer),\n asOrganization: nullable(text),\n country: nullable(text),\n },\n primaryKey: ['id'],\n uuidV7: 'id',\n indexes: [['messageId']],\n references: [{ columns: ['messageId'], table: 'message', foreignColumns: ['id'] }],\n }),\n} satisfies Record<string, TableSpec>;\n\nexport type TableKey = keyof typeof TABLES;\n\n/** The engine's schema when the config names none. */\nexport const DEFAULT_SCHEMA = 'workflow';\n\n/** `eventId` → `event_id`. */\nexport function columnName(key: string): string {\n return key.replace(/[A-Z]/g, (c) => `_${c.toLowerCase()}`);\n}\n\nconst quote = (name: string) => `\"${name.replace(/\"/g, '\"\"')}\"`;\n\nconst SQL_TYPES: Record<ColumnType, string> = {\n uuid: 'uuid',\n text: 'text',\n jsonb: 'jsonb',\n timestamptz: 'timestamptz',\n integer: 'integer',\n boolean: 'boolean',\n};\n\n/**\n * Plain Postgres DDL for every table — for a host without a migration tool, and the tests. A\n * host that migrates with drizzle generates `renderDrizzleSchema` instead and lets drizzle-kit\n * write the migration.\n */\nexport function renderPostgresDdl(schema = DEFAULT_SCHEMA): string {\n const s = quote(schema);\n const out = [`CREATE SCHEMA IF NOT EXISTS ${s};`];\n for (const spec of Object.values(TABLES)) {\n const lines = Object.entries(spec.columns).map(\n ([key, column]) =>\n ` ${quote(columnName(key))} ${SQL_TYPES[column.type]}${column.nullable ? '' : ' NOT NULL'}`\n );\n lines.push(` PRIMARY KEY (${spec.primaryKey.map((k) => quote(columnName(k))).join(', ')})`);\n if (spec.uuidV7 !== undefined) {\n lines.push(\n ` CONSTRAINT ${quote(`${spec.name}_uuid_v7`)} CHECK (substring(${quote(columnName(spec.uuidV7))}::text, 15, 1) = '7')`\n );\n }\n for (const ref of spec.references ?? []) {\n const target = TABLES[ref.table as TableKey];\n lines.push(\n ` FOREIGN KEY (${ref.columns.map((k) => quote(columnName(k))).join(', ')}) REFERENCES ${s}.${quote(target.name)} (${ref.foreignColumns.map((k) => quote(columnName(k))).join(', ')})`\n );\n }\n out.push(`CREATE TABLE IF NOT EXISTS ${s}.${quote(spec.name)} (\\n${lines.join(',\\n')}\\n);`);\n const index = (unique: boolean) => (keys: readonly string[]) => {\n const cols = keys.map(columnName);\n out.push(\n `CREATE ${unique ? 'UNIQUE ' : ''}INDEX IF NOT EXISTS ${quote(`${spec.name}_${cols.join('_')}_index`)} ON ${s}.${quote(spec.name)} (${cols.map(quote).join(', ')});`\n );\n };\n (spec.uniqueIndexes ?? []).forEach(index(true));\n (spec.indexes ?? []).forEach(index(false));\n }\n return `${out.join('\\n')}\\n`;\n}\n\nconst DRIZZLE_TYPES: Record<ColumnType, (column: string) => string> = {\n uuid: (c) => `uuid('${c}')`,\n text: (c) => `text('${c}')`,\n jsonb: (c) => `jsonb('${c}')`,\n timestamptz: (c) => `timestamp('${c}', { mode: 'string', withTimezone: true })`,\n integer: (c) => `integer('${c}')`,\n boolean: (c) => `boolean('${c}')`,\n};\n\nconst exportName = (key: string) => `workflow${key.charAt(0).toUpperCase()}${key.slice(1)}`;\n\n/**\n * The tables as one drizzle file: `export const workflowSchema = pgSchema(<schema>)` and every\n * table as `workflowSchema.table(...)`. The host re-exports it from its drizzle schema and\n * generates the migration with drizzle-kit, so the migration history stays the host's. The\n * output is deterministic — regenerate and diff it in CI to catch an SDK upgrade that changed the\n * tables.\n */\nexport function renderDrizzleSchema(schema = DEFAULT_SCHEMA): string {\n const specs = Object.entries(TABLES) as [TableKey, TableSpec][];\n const used = new Set<string>(['pgSchema']);\n const body: string[] = [];\n let needsSql = false;\n for (const [key, spec] of specs) {\n const columns = Object.entries(spec.columns).map(([prop, column]) => {\n used.add(column.type === 'timestamptz' ? 'timestamp' : column.type);\n const doc = column.doc === undefined ? '' : ` /** ${column.doc} */\\n`;\n const key =\n spec.primaryKey.length === 1 && spec.primaryKey[0] === prop ? '.primaryKey()' : '';\n return `${doc} ${prop}: ${DRIZZLE_TYPES[column.type](columnName(prop))}${key}${column.nullable ? '' : '.notNull()'},`;\n });\n const extras: string[] = [];\n if (spec.primaryKey.length > 1) {\n used.add('primaryKey');\n extras.push(\n `primaryKey({ columns: [${spec.primaryKey.map((k) => `table.${k}`).join(', ')}] })`\n );\n }\n for (const keys of spec.uniqueIndexes ?? []) {\n used.add('uniqueIndex');\n extras.push(`uniqueIndex().on(${keys.map((k) => `table.${k}`).join(', ')})`);\n }\n for (const keys of spec.indexes ?? []) {\n used.add('index');\n extras.push(`index().on(${keys.map((k) => `table.${k}`).join(', ')})`);\n }\n for (const ref of spec.references ?? []) {\n used.add('foreignKey');\n extras.push(\n `foreignKey({ columns: [${ref.columns.map((k) => `table.${k}`).join(', ')}], foreignColumns: [${ref.foreignColumns.map((k) => `${exportName(ref.table)}.${k}`).join(', ')}] })`\n );\n }\n if (spec.uuidV7 !== undefined) {\n used.add('check');\n needsSql = true;\n extras.push(\n `check('${spec.name}_uuid_v7', sql\\`substring(\\${table.${spec.uuidV7}}::text, 15, 1) = '7'\\`)`\n );\n }\n const third =\n extras.length === 0\n ? ''\n : `,\\n (table) => [\\n${extras.map((e) => ` ${e},`).join('\\n')}\\n ]`;\n body.push(\n `/** ${spec.doc} */\\nexport const ${exportName(key)} = workflowSchema.table(\\n '${spec.name}',\\n {\\n${columns.join('\\n')}\\n }${third}\\n);`\n );\n }\n const imports = [...used].sort();\n return [\n '// Generated by `workflow-ui generate` from @shware/workflow — do not edit; regenerate after',\n '// upgrading the SDK and let drizzle-kit write the migration.',\n ...(needsSql ? [\"import { sql } from 'drizzle-orm';\"] : []),\n `import {\\n${imports.map((name) => ` ${name},`).join('\\n')}\\n} from 'drizzle-orm/pg-core';`,\n '',\n `export const workflowSchema = pgSchema('${schema}');`,\n '',\n body.join('\\n\\n'),\n '',\n ].join('\\n');\n}\n"],"mappings":"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"}
|
package/dist/templates.d.cts
CHANGED
package/dist/templates.d.mts
CHANGED
package/dist/webpush.d.cts
CHANGED
package/dist/webpush.d.mts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shware/workflow",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/ShwareHQ/shware-sdk.git"
|
|
@@ -149,27 +149,28 @@
|
|
|
149
149
|
},
|
|
150
150
|
"dependencies": {
|
|
151
151
|
"@slack/types": "^3.2.0",
|
|
152
|
-
"@types/ms": "^2.1.0",
|
|
153
152
|
"discord-api-types": "^0.38.56",
|
|
154
|
-
"ms": "^2.1.3"
|
|
155
|
-
"zod": "^4.6.5"
|
|
153
|
+
"ms": "^2.1.3"
|
|
156
154
|
},
|
|
157
155
|
"devDependencies": {
|
|
158
|
-
"@electric-sql/pglite": "^0.5.
|
|
156
|
+
"@electric-sql/pglite": "^0.5.10",
|
|
159
157
|
"@repo/typescript-config": "0.0.0",
|
|
160
|
-
"@types/
|
|
161
|
-
"@types/
|
|
162
|
-
"@types/react
|
|
158
|
+
"@types/ms": "^2.1.0",
|
|
159
|
+
"@types/node": "^26.6.5",
|
|
160
|
+
"@types/react": "^19.3.0",
|
|
161
|
+
"@types/react-dom": "^19.3.0",
|
|
163
162
|
"postgres": "^3.4.9",
|
|
164
|
-
"react": "^19.
|
|
165
|
-
"react-dom": "^19.
|
|
163
|
+
"react": "^19.3.1",
|
|
164
|
+
"react-dom": "^19.3.1",
|
|
166
165
|
"typescript": "^7.0.2",
|
|
167
|
-
"vitest": "^5.0.
|
|
166
|
+
"vitest": "^5.0.5",
|
|
167
|
+
"zod": "^4.6.7"
|
|
168
168
|
},
|
|
169
169
|
"peerDependencies": {
|
|
170
170
|
"postgres": ">=3.4.0",
|
|
171
171
|
"react": ">=19",
|
|
172
|
-
"react-dom": ">=19"
|
|
172
|
+
"react-dom": ">=19",
|
|
173
|
+
"zod": "^4.6.5"
|
|
173
174
|
},
|
|
174
175
|
"peerDependenciesMeta": {
|
|
175
176
|
"postgres": {
|