Skip to content

Commit 32e76c9

Browse files
pgflow botjumski
authored andcommitted
feat: build edge worker for npm
1 parent 5e9c0a9 commit 32e76c9

9 files changed

Lines changed: 60 additions & 18 deletions

File tree

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
"@pgflow/core": minor
3+
"@pgflow/dsl": minor
4+
"@pgflow/client": minor
5+
"@pgflow/edge-worker": minor
6+
"pgflow": minor
7+
---
8+
9+
Publish `@pgflow/edge-worker` to npm and add Node/Bun process runtime support.

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@
66
"scripts": {
77
"build": "nx run-many --target=build --all",
88
"version": "pnpm changeset version && ./scripts/update-jsr-json-version.sh",
9-
"validate:publish:npm": "pnpm nx run-many -t build --exclude=demo,website,example-flows && git status && pnpm publish --dry-run --provenance --recursive --filter=!./pkgs/edge-worker",
9+
"smoke:edge-worker:dist": "pnpm nx build edge-worker && node ./scripts/smoke-edge-worker-dist.mjs",
10+
"validate:publish:npm": "pnpm nx run-many -t build --exclude=demo,website,example-flows && pnpm smoke:edge-worker:dist && git status && pnpm publish --dry-run --provenance --recursive",
1011
"validate:publish:jsr": "cd ./pkgs/edge-worker && jsr publish --dry-run --allow-slow-types",
1112
"validate:publish": "pnpm run validate:publish:npm && pnpm run validate:publish:jsr",
12-
"publish:npm": "pnpm nx run-many -t build --exclude=demo,website,example-flows && pnpm publish --provenance --recursive --filter=!./pkgs/edge-worker",
13+
"publish:npm": "pnpm nx run-many -t build --exclude=demo,website,example-flows && pnpm publish --provenance --recursive",
1314
"publish:jsr": "cd ./pkgs/edge-worker && jsr publish --allow-slow-types",
1415
"changeset:tag": "pnpm changeset tag && git push --follow-tags",
1516
"release": "git status && pnpm run validate:publish && pnpm run publish:npm && pnpm run publish:jsr && pnpm run changeset:tag"

pkgs/edge-worker/project.json

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,9 @@
88
"executor": "nx:noop"
99
},
1010
"build": {
11-
"executor": "nx:noop",
12-
"dependsOn": ["^build"]
13-
},
14-
"_build_disabled": {
1511
"executor": "@nx/js:tsc",
12+
"outputs": ["{options.outputPath}"],
13+
"dependsOn": ["^build"],
1614
"options": {
1715
"outputPath": "pkgs/edge-worker/dist",
1816
"main": "pkgs/edge-worker/src/index.ts",

pkgs/edge-worker/src/control-plane/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* ```typescript
99
* // Using namespace import (recommended)
1010
* import { ControlPlane } from '@pgflow/edge-worker';
11-
* import * as flows from '../../flows/index.ts';
11+
* import * as flows from '../../flows/index.js';
1212
*
1313
* ControlPlane.serve(flows);
1414
* ```
@@ -17,7 +17,7 @@
1717
* ```typescript
1818
* // Using array (legacy)
1919
* import { ControlPlane } from '@pgflow/edge-worker';
20-
* import { MyFlow } from '../../flows/my_flow.ts';
20+
* import { MyFlow } from '../../flows/my_flow.js';
2121
*
2222
* ControlPlane.serve([MyFlow]);
2323
* ```

pkgs/edge-worker/src/platform/processDeps.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ type CryptoLike = {
2121

2222
export function getProcessDeps(): ProcessDeps {
2323
const processLike = (globalThis as { process?: ProcessLike }).process;
24-
const cryptoLike = globalThis.crypto as CryptoLike | undefined;
24+
const cryptoLike = (globalThis as { crypto?: CryptoLike }).crypto;
2525

2626
if (!processLike?.env || !processLike.on || !processLike.exit || !cryptoLike?.randomUUID) {
2727
throw new Error('Process runtime is not available');

pkgs/edge-worker/src/platform/resolveConnection.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { isLocalSupabaseEnv } from '../shared/localDetection.ts';
1+
import { isLocalSupabaseEnv } from '../shared/localDetection.js';
22
import postgres from 'postgres';
33

44
/**

pkgs/edge-worker/src/shared/authValidation.ts

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
1-
import { timingSafeEqual } from '@std/crypto/timing-safe-equal';
2-
import { isLocalSupabaseEnv } from './localDetection.ts';
1+
import { isLocalSupabaseEnv } from './localDetection.js';
2+
3+
function timingSafeEqualBytes(a: Uint8Array, b: Uint8Array): boolean {
4+
if (a.length !== b.length) {
5+
return false;
6+
}
7+
8+
let diff = 0;
9+
10+
for (let index = 0; index < a.length; index += 1) {
11+
diff |= a[index] ^ b[index];
12+
}
13+
14+
return diff === 0;
15+
}
316

417
export interface AuthValidationResult {
518
valid: boolean;
@@ -38,12 +51,7 @@ export function validateServiceRoleAuth(
3851
const authBytes = encoder.encode(authHeader);
3952
const expectedBytes = encoder.encode(expected);
4053

41-
// Length check first (timingSafeEqual requires same length)
42-
if (authBytes.length !== expectedBytes.length) {
43-
return { valid: false, error: 'Invalid Authorization header' };
44-
}
45-
46-
if (!timingSafeEqual(authBytes, expectedBytes)) {
54+
if (!timingSafeEqualBytes(authBytes, expectedBytes)) {
4755
return { valid: false, error: 'Invalid Authorization header' };
4856
}
4957

pkgs/edge-worker/tsconfig.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
"rootDir": "src",
77
"outDir": "dist",
88
"tsBuildInfoFile": "dist/tsconfig.lib.tsbuildinfo",
9+
"lib": ["es2022", "dom", "dom.iterable"],
910
"typeRoots": ["./node_modules/@types", "."],
1011
"types": [
1112
"node",

scripts/smoke-edge-worker-dist.mjs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import * as edgeWorker from '../pkgs/edge-worker/dist/index.js';
2+
import * as internal from '../pkgs/edge-worker/dist/_internal.js';
3+
import * as testing from '../pkgs/edge-worker/dist/testing.js';
4+
5+
const requiredExports = [
6+
['EdgeWorker', edgeWorker.EdgeWorker],
7+
['createQueueWorker', edgeWorker.createQueueWorker],
8+
['createFlowWorker', edgeWorker.createFlowWorker],
9+
['ProcessPlatformAdapter', edgeWorker.ProcessPlatformAdapter],
10+
['SupabasePlatformAdapter', edgeWorker.SupabasePlatformAdapter],
11+
];
12+
13+
for (const [name, value] of requiredExports) {
14+
if (value === undefined) {
15+
throw new Error(`Missing edge-worker export: ${name}`);
16+
}
17+
}
18+
19+
if (Object.keys(internal).length === 0) {
20+
throw new Error('Expected _internal export surface to load');
21+
}
22+
23+
if (Object.keys(testing).length === 0) {
24+
throw new Error('Expected testing export surface to load');
25+
}

0 commit comments

Comments
 (0)