@rocicorp/zero 1.4.0-canary.3 → 1.4.0-canary.4

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.
@@ -1,6 +1,6 @@
1
1
  var package_default = {
2
2
  name: "@rocicorp/zero",
3
- version: "1.4.0-canary.3",
3
+ version: "1.4.0-canary.4",
4
4
  description: "Zero is a web framework for serverless web development.",
5
5
  homepage: "https://zero.rocicorp.dev",
6
6
  bugs: { "url": "https://bugs.rocicorp.dev" },
@@ -1 +1 @@
1
- {"version":3,"file":"package.js","names":[],"sources":["../../package.json"],"sourcesContent":["{\n \"name\": \"@rocicorp/zero\",\n \"version\": \"1.4.0-canary.3\",\n \"description\": \"Zero is a web framework for serverless web development.\",\n \"homepage\": \"https://zero.rocicorp.dev\",\n \"bugs\": {\n \"url\": \"https://bugs.rocicorp.dev\"\n },\n \"license\": \"Apache-2.0\",\n \"author\": \"Rocicorp, Inc.\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/rocicorp/mono.git\",\n \"directory\": \"packages/zero\"\n },\n \"bin\": {\n \"analyze-query\": \"./out/zero/src/analyze-query.js\",\n \"ast-to-zql\": \"./out/zero/src/ast-to-zql.js\",\n \"transform-query\": \"./out/zero/src/transform-query.js\",\n \"zero-build-schema\": \"./out/zero/src/build-schema.js\",\n \"zero-cache\": \"./out/zero/src/cli.js\",\n \"zero-cache-dev\": \"./out/zero/src/zero-cache-dev.js\",\n \"zero-deploy-permissions\": \"./out/zero/src/deploy-permissions.js\",\n \"zero-out\": \"./out/zero/src/zero-out.js\"\n },\n \"files\": [\n \"out\",\n \"!*.tsbuildinfo\"\n ],\n \"type\": \"module\",\n \"main\": \"out/zero/src/zero.js\",\n \"module\": \"out/zero/src/zero.js\",\n \"types\": \"out/zero/src/zero.d.ts\",\n \"exports\": {\n \".\": {\n \"types\": \"./out/zero/src/zero.d.ts\",\n \"default\": \"./out/zero/src/zero.js\"\n },\n \"./analyze\": {\n \"types\": \"./out/zero/src/analyze.d.ts\",\n \"default\": \"./out/zero/src/analyze.js\"\n },\n \"./bindings\": {\n \"types\": \"./out/zero/src/bindings.d.ts\",\n \"default\": \"./out/zero/src/bindings.js\"\n },\n \"./change-protocol/v0\": {\n \"types\": \"./out/zero/src/change-protocol/v0.d.ts\",\n \"default\": \"./out/zero/src/change-protocol/v0.js\"\n },\n \"./expo-sqlite\": {\n \"types\": \"./out/zero/src/expo-sqlite.d.ts\",\n \"default\": \"./out/zero/src/expo-sqlite.js\"\n },\n \"./op-sqlite\": {\n \"types\": \"./out/zero/src/op-sqlite.d.ts\",\n \"default\": \"./out/zero/src/op-sqlite.js\"\n },\n \"./pg\": {\n \"types\": \"./out/zero/src/pg.d.ts\",\n \"default\": \"./out/zero/src/pg.js\"\n },\n \"./react\": {\n \"types\": \"./out/zero/src/react.d.ts\",\n \"default\": \"./out/zero/src/react.js\"\n },\n \"./react-native\": {\n \"types\": \"./out/zero/src/react-native.d.ts\",\n \"default\": \"./out/zero/src/react-native.js\"\n },\n \"./server\": {\n \"types\": \"./out/zero/src/server.d.ts\",\n \"default\": \"./out/zero/src/server.js\"\n },\n \"./server/adapters/drizzle\": {\n \"types\": \"./out/zero/src/adapters/drizzle.d.ts\",\n \"default\": \"./out/zero/src/adapters/drizzle.js\"\n },\n \"./server/adapters/kysely\": {\n \"types\": \"./out/zero/src/adapters/kysely.d.ts\",\n \"default\": \"./out/zero/src/adapters/kysely.js\"\n },\n \"./server/adapters/prisma\": {\n \"types\": \"./out/zero/src/adapters/prisma.d.ts\",\n \"default\": \"./out/zero/src/adapters/prisma.js\"\n },\n \"./server/adapters/pg\": {\n \"types\": \"./out/zero/src/adapters/pg.d.ts\",\n \"default\": \"./out/zero/src/adapters/pg.js\"\n },\n \"./server/adapters/postgresjs\": {\n \"types\": \"./out/zero/src/adapters/postgresjs.d.ts\",\n \"default\": \"./out/zero/src/adapters/postgresjs.js\"\n },\n \"./solid\": {\n \"types\": \"./out/zero/src/solid.d.ts\",\n \"default\": \"./out/zero/src/solid.js\"\n },\n \"./sqlite\": {\n \"types\": \"./out/zero/src/sqlite.d.ts\",\n \"default\": \"./out/zero/src/sqlite.js\"\n },\n \"./zqlite\": {\n \"types\": \"./out/zero/src/zqlite.d.ts\",\n \"default\": \"./out/zero/src/zqlite.js\"\n }\n },\n \"scripts\": {\n \"build\": \"node --experimental-strip-types --no-warnings tool/build.ts\",\n \"build:watch\": \"node --experimental-strip-types --no-warnings tool/build.ts --watch\",\n \"check-types\": \"tsc -p tsconfig.client.json && tsc -p tsconfig.server.json\",\n \"check-types:client:watch\": \"tsc -p tsconfig.client.json --watch\",\n \"check-types:server:watch\": \"tsc -p tsconfig.server.json --watch\",\n \"format\": \"oxfmt .\",\n \"check-format\": \"oxfmt --check .\",\n \"lint\": \"oxlint --type-aware src/\",\n \"docs\": \"node --experimental-strip-types --no-warnings tool/generate-docs.ts\",\n \"docs:server\": \"node --watch --experimental-strip-types --no-warnings tool/generate-docs.ts --server\",\n \"fmt\": \"oxfmt .\",\n \"check-fmt\": \"oxfmt --check .\"\n },\n \"dependencies\": {\n \"@badrap/valita\": \"0.3.11\",\n \"@databases/escape-identifier\": \"^1.0.3\",\n \"@databases/sql\": \"^3.3.0\",\n \"@dotenvx/dotenvx\": \"^1.39.0\",\n \"@drdgvhbh/postgres-error-codes\": \"^0.0.6\",\n \"@fastify/cors\": \"^10.0.0\",\n \"@fastify/websocket\": \"^11.0.0\",\n \"@google-cloud/precise-date\": \"^4.0.0\",\n \"@opentelemetry/api\": \"^1.9.0\",\n \"@opentelemetry/api-logs\": \"^0.203.0\",\n \"@opentelemetry/auto-instrumentations-node\": \"^0.62.0\",\n \"@opentelemetry/exporter-metrics-otlp-http\": \"^0.203.0\",\n \"@opentelemetry/resources\": \"^2.0.1\",\n \"@opentelemetry/sdk-metrics\": \"^2.0.1\",\n \"@opentelemetry/sdk-node\": \"^0.203.0\",\n \"@opentelemetry/sdk-trace-node\": \"^2.0.1\",\n \"@postgresql-typed/oids\": \"^0.2.0\",\n \"@rocicorp/lock\": \"^1.0.4\",\n \"@rocicorp/logger\": \"^5.4.0\",\n \"@rocicorp/resolver\": \"^1.0.2\",\n \"@rocicorp/zero-sqlite3\": \"^1.0.17\",\n \"@standard-schema/spec\": \"^1.0.0\",\n \"@types/basic-auth\": \"^1.1.8\",\n \"@types/ws\": \"^8.5.12\",\n \"basic-auth\": \"^2.0.1\",\n \"chalk-template\": \"^1.1.0\",\n \"chokidar\": \"^4.0.1\",\n \"cloudevents\": \"^10.0.0\",\n \"command-line-args\": \"^6.0.1\",\n \"command-line-usage\": \"^7.0.3\",\n \"compare-utf8\": \"^0.2.0\",\n \"defu\": \"^6.1.4\",\n \"eventemitter3\": \"^5.0.1\",\n \"fastify\": \"^5.0.0\",\n \"is-in-subnet\": \"^4.0.1\",\n \"jose\": \"^5.9.3\",\n \"js-xxhash\": \"^4.0.0\",\n \"json-custom-numbers\": \"^3.1.1\",\n \"kasi\": \"^1.1.0\",\n \"nanoid\": \"^5.1.2\",\n \"oxfmt\": \"^0.45.0\",\n \"parse-prometheus-text-format\": \"^1.1.1\",\n \"pg-format\": \"npm:pg-format-fix@^1.0.5\",\n \"postgres\": \"3.4.7\",\n \"semver\": \"^7.5.4\",\n \"tsx\": \"^4.21.0\",\n \"url-pattern\": \"^1.0.3\",\n \"urlpattern-polyfill\": \"^10.1.0\",\n \"ws\": \"^8.18.1\"\n },\n \"devDependencies\": {\n \"@op-engineering/op-sqlite\": \">=15\",\n \"@vitest/runner\": \"4.1.3\",\n \"analyze-query\": \"0.0.0\",\n \"ast-to-zql\": \"0.0.0\",\n \"expo-sqlite\": \">=15\",\n \"replicache\": \"15.2.1\",\n \"shared\": \"0.0.0\",\n \"syncpack\": \"^14.3.0\",\n \"typedoc\": \"^0.28.17\",\n \"typedoc-plugin-markdown\": \"^4.10.0\",\n \"typescript\": \"~6.0.2\",\n \"vite\": \"8.0.3\",\n \"vitest\": \"4.1.3\",\n \"zero-cache\": \"0.0.0\",\n \"zero-client\": \"0.0.0\",\n \"zero-pg\": \"0.0.0\",\n \"zero-protocol\": \"0.0.0\",\n \"zero-react\": \"0.0.0\",\n \"zero-server\": \"0.0.0\",\n \"zero-solid\": \"0.0.0\",\n \"zqlite\": \"0.0.0\"\n },\n \"peerDependencies\": {\n \"@op-engineering/op-sqlite\": \">=15\",\n \"expo-sqlite\": \">=15\",\n \"kysely\": \"^0.28.16\"\n },\n \"peerDependenciesMeta\": {\n \"kysely\": {\n \"optional\": true\n },\n \"expo-sqlite\": {\n \"optional\": true\n },\n \"@op-engineering/op-sqlite\": {\n \"optional\": true\n }\n },\n \"engines\": {\n \"node\": \">=22\"\n }\n}"],"mappings":""}
1
+ {"version":3,"file":"package.js","names":[],"sources":["../../package.json"],"sourcesContent":["{\n \"name\": \"@rocicorp/zero\",\n \"version\": \"1.4.0-canary.4\",\n \"description\": \"Zero is a web framework for serverless web development.\",\n \"homepage\": \"https://zero.rocicorp.dev\",\n \"bugs\": {\n \"url\": \"https://bugs.rocicorp.dev\"\n },\n \"license\": \"Apache-2.0\",\n \"author\": \"Rocicorp, Inc.\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/rocicorp/mono.git\",\n \"directory\": \"packages/zero\"\n },\n \"bin\": {\n \"analyze-query\": \"./out/zero/src/analyze-query.js\",\n \"ast-to-zql\": \"./out/zero/src/ast-to-zql.js\",\n \"transform-query\": \"./out/zero/src/transform-query.js\",\n \"zero-build-schema\": \"./out/zero/src/build-schema.js\",\n \"zero-cache\": \"./out/zero/src/cli.js\",\n \"zero-cache-dev\": \"./out/zero/src/zero-cache-dev.js\",\n \"zero-deploy-permissions\": \"./out/zero/src/deploy-permissions.js\",\n \"zero-out\": \"./out/zero/src/zero-out.js\"\n },\n \"files\": [\n \"out\",\n \"!*.tsbuildinfo\"\n ],\n \"type\": \"module\",\n \"main\": \"out/zero/src/zero.js\",\n \"module\": \"out/zero/src/zero.js\",\n \"types\": \"out/zero/src/zero.d.ts\",\n \"exports\": {\n \".\": {\n \"types\": \"./out/zero/src/zero.d.ts\",\n \"default\": \"./out/zero/src/zero.js\"\n },\n \"./analyze\": {\n \"types\": \"./out/zero/src/analyze.d.ts\",\n \"default\": \"./out/zero/src/analyze.js\"\n },\n \"./bindings\": {\n \"types\": \"./out/zero/src/bindings.d.ts\",\n \"default\": \"./out/zero/src/bindings.js\"\n },\n \"./change-protocol/v0\": {\n \"types\": \"./out/zero/src/change-protocol/v0.d.ts\",\n \"default\": \"./out/zero/src/change-protocol/v0.js\"\n },\n \"./expo-sqlite\": {\n \"types\": \"./out/zero/src/expo-sqlite.d.ts\",\n \"default\": \"./out/zero/src/expo-sqlite.js\"\n },\n \"./op-sqlite\": {\n \"types\": \"./out/zero/src/op-sqlite.d.ts\",\n \"default\": \"./out/zero/src/op-sqlite.js\"\n },\n \"./pg\": {\n \"types\": \"./out/zero/src/pg.d.ts\",\n \"default\": \"./out/zero/src/pg.js\"\n },\n \"./react\": {\n \"types\": \"./out/zero/src/react.d.ts\",\n \"default\": \"./out/zero/src/react.js\"\n },\n \"./react-native\": {\n \"types\": \"./out/zero/src/react-native.d.ts\",\n \"default\": \"./out/zero/src/react-native.js\"\n },\n \"./server\": {\n \"types\": \"./out/zero/src/server.d.ts\",\n \"default\": \"./out/zero/src/server.js\"\n },\n \"./server/adapters/drizzle\": {\n \"types\": \"./out/zero/src/adapters/drizzle.d.ts\",\n \"default\": \"./out/zero/src/adapters/drizzle.js\"\n },\n \"./server/adapters/kysely\": {\n \"types\": \"./out/zero/src/adapters/kysely.d.ts\",\n \"default\": \"./out/zero/src/adapters/kysely.js\"\n },\n \"./server/adapters/prisma\": {\n \"types\": \"./out/zero/src/adapters/prisma.d.ts\",\n \"default\": \"./out/zero/src/adapters/prisma.js\"\n },\n \"./server/adapters/pg\": {\n \"types\": \"./out/zero/src/adapters/pg.d.ts\",\n \"default\": \"./out/zero/src/adapters/pg.js\"\n },\n \"./server/adapters/postgresjs\": {\n \"types\": \"./out/zero/src/adapters/postgresjs.d.ts\",\n \"default\": \"./out/zero/src/adapters/postgresjs.js\"\n },\n \"./solid\": {\n \"types\": \"./out/zero/src/solid.d.ts\",\n \"default\": \"./out/zero/src/solid.js\"\n },\n \"./sqlite\": {\n \"types\": \"./out/zero/src/sqlite.d.ts\",\n \"default\": \"./out/zero/src/sqlite.js\"\n },\n \"./zqlite\": {\n \"types\": \"./out/zero/src/zqlite.d.ts\",\n \"default\": \"./out/zero/src/zqlite.js\"\n }\n },\n \"scripts\": {\n \"build\": \"node --experimental-strip-types --no-warnings tool/build.ts\",\n \"build:watch\": \"node --experimental-strip-types --no-warnings tool/build.ts --watch\",\n \"check-types\": \"tsc -p tsconfig.client.json && tsc -p tsconfig.server.json\",\n \"check-types:client:watch\": \"tsc -p tsconfig.client.json --watch\",\n \"check-types:server:watch\": \"tsc -p tsconfig.server.json --watch\",\n \"format\": \"oxfmt .\",\n \"check-format\": \"oxfmt --check .\",\n \"lint\": \"oxlint --type-aware src/\",\n \"docs\": \"node --experimental-strip-types --no-warnings tool/generate-docs.ts\",\n \"docs:server\": \"node --watch --experimental-strip-types --no-warnings tool/generate-docs.ts --server\",\n \"fmt\": \"oxfmt .\",\n \"check-fmt\": \"oxfmt --check .\"\n },\n \"dependencies\": {\n \"@badrap/valita\": \"0.3.11\",\n \"@databases/escape-identifier\": \"^1.0.3\",\n \"@databases/sql\": \"^3.3.0\",\n \"@dotenvx/dotenvx\": \"^1.39.0\",\n \"@drdgvhbh/postgres-error-codes\": \"^0.0.6\",\n \"@fastify/cors\": \"^10.0.0\",\n \"@fastify/websocket\": \"^11.0.0\",\n \"@google-cloud/precise-date\": \"^4.0.0\",\n \"@opentelemetry/api\": \"^1.9.0\",\n \"@opentelemetry/api-logs\": \"^0.203.0\",\n \"@opentelemetry/auto-instrumentations-node\": \"^0.62.0\",\n \"@opentelemetry/exporter-metrics-otlp-http\": \"^0.203.0\",\n \"@opentelemetry/resources\": \"^2.0.1\",\n \"@opentelemetry/sdk-metrics\": \"^2.0.1\",\n \"@opentelemetry/sdk-node\": \"^0.203.0\",\n \"@opentelemetry/sdk-trace-node\": \"^2.0.1\",\n \"@postgresql-typed/oids\": \"^0.2.0\",\n \"@rocicorp/lock\": \"^1.0.4\",\n \"@rocicorp/logger\": \"^5.4.0\",\n \"@rocicorp/resolver\": \"^1.0.2\",\n \"@rocicorp/zero-sqlite3\": \"^1.0.17\",\n \"@standard-schema/spec\": \"^1.0.0\",\n \"@types/basic-auth\": \"^1.1.8\",\n \"@types/ws\": \"^8.5.12\",\n \"basic-auth\": \"^2.0.1\",\n \"chalk-template\": \"^1.1.0\",\n \"chokidar\": \"^4.0.1\",\n \"cloudevents\": \"^10.0.0\",\n \"command-line-args\": \"^6.0.1\",\n \"command-line-usage\": \"^7.0.3\",\n \"compare-utf8\": \"^0.2.0\",\n \"defu\": \"^6.1.4\",\n \"eventemitter3\": \"^5.0.1\",\n \"fastify\": \"^5.0.0\",\n \"is-in-subnet\": \"^4.0.1\",\n \"jose\": \"^5.9.3\",\n \"js-xxhash\": \"^4.0.0\",\n \"json-custom-numbers\": \"^3.1.1\",\n \"kasi\": \"^1.1.0\",\n \"nanoid\": \"^5.1.2\",\n \"oxfmt\": \"^0.45.0\",\n \"parse-prometheus-text-format\": \"^1.1.1\",\n \"pg-format\": \"npm:pg-format-fix@^1.0.5\",\n \"postgres\": \"3.4.7\",\n \"semver\": \"^7.5.4\",\n \"tsx\": \"^4.21.0\",\n \"url-pattern\": \"^1.0.3\",\n \"urlpattern-polyfill\": \"^10.1.0\",\n \"ws\": \"^8.18.1\"\n },\n \"devDependencies\": {\n \"@op-engineering/op-sqlite\": \">=15\",\n \"@vitest/runner\": \"4.1.3\",\n \"analyze-query\": \"0.0.0\",\n \"ast-to-zql\": \"0.0.0\",\n \"expo-sqlite\": \">=15\",\n \"replicache\": \"15.2.1\",\n \"shared\": \"0.0.0\",\n \"syncpack\": \"^14.3.0\",\n \"typedoc\": \"^0.28.17\",\n \"typedoc-plugin-markdown\": \"^4.10.0\",\n \"typescript\": \"~6.0.2\",\n \"vite\": \"8.0.3\",\n \"vitest\": \"4.1.3\",\n \"zero-cache\": \"0.0.0\",\n \"zero-client\": \"0.0.0\",\n \"zero-pg\": \"0.0.0\",\n \"zero-protocol\": \"0.0.0\",\n \"zero-react\": \"0.0.0\",\n \"zero-server\": \"0.0.0\",\n \"zero-solid\": \"0.0.0\",\n \"zqlite\": \"0.0.0\"\n },\n \"peerDependencies\": {\n \"@op-engineering/op-sqlite\": \">=15\",\n \"expo-sqlite\": \">=15\",\n \"kysely\": \"^0.28.16\"\n },\n \"peerDependenciesMeta\": {\n \"kysely\": {\n \"optional\": true\n },\n \"expo-sqlite\": {\n \"optional\": true\n },\n \"@op-engineering/op-sqlite\": {\n \"optional\": true\n }\n },\n \"engines\": {\n \"node\": \">=22\"\n }\n}"],"mappings":""}
@@ -11,6 +11,7 @@ import { watch } from "chokidar";
11
11
  //#region src/zero-cache-dev.ts
12
12
  var deployPermissionsScript = "zero-deploy-permissions";
13
13
  var zeroCacheScript = "zero-cache";
14
+ var startupMessageEnv = "ZERO_ENABLE_STARTUP_MESSAGE";
14
15
  function killProcess(childProcess) {
15
16
  if (!childProcess || childProcess.exitCode !== null) return Promise.resolve();
16
17
  const { resolve, promise } = resolver();
@@ -93,6 +94,7 @@ async function main() {
93
94
  ["ZERO_CVR_MAX_CONNS"]: "6",
94
95
  ["ZERO_UPSTREAM_MAX_CONNS"]: "6",
95
96
  ["NODE_ENV"]: "development",
97
+ [startupMessageEnv]: "1",
96
98
  ...process.env,
97
99
  ...zeroCacheEnv
98
100
  },
@@ -1 +1 @@
1
- {"version":3,"file":"zero-cache-dev.js","names":[],"sources":["../../../src/zero-cache-dev.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport '../../shared/src/dotenv.ts';\n\nimport {spawn, type ChildProcess} from 'node:child_process';\nimport {resolver} from '@rocicorp/resolver';\nimport {watch} from 'chokidar';\nimport {createLogContext} from '../../shared/src/logging.ts';\nimport {parseOptionsAdvanced} from '../../shared/src/options.ts';\nimport * as v from '../../shared/src/valita.ts';\nimport {\n ZERO_ENV_VAR_PREFIX,\n zeroOptions,\n} from '../../zero-cache/src/config/zero-config.ts';\nimport {deployPermissionsOptions} from '../../zero-cache/src/scripts/permissions.ts';\n\nconst deployPermissionsScript = 'zero-deploy-permissions';\nconst zeroCacheScript = 'zero-cache';\n\nfunction killProcess(childProcess: ChildProcess | undefined) {\n if (!childProcess || childProcess.exitCode !== null) {\n return Promise.resolve();\n }\n const {resolve, promise} = resolver();\n childProcess.on('exit', resolve);\n // Use SIGQUIT in particular since this will cause\n // a fast zero-cache shutdown instead of a graceful drain.\n childProcess.kill('SIGQUIT');\n return promise;\n}\n\nasync function main() {\n const {config} = parseOptionsAdvanced(\n {\n schema: {\n path: {\n type: v.string().optional(),\n desc: ['Relative path to the file containing permissions.'],\n alias: 'p',\n deprecated: [\n 'Permissions are deprecated and will be removed in an upcoming release. See: https://zero.rocicorp.dev/docs/auth.',\n ],\n },\n },\n ...zeroOptions,\n },\n {\n envNamePrefix: ZERO_ENV_VAR_PREFIX,\n // TODO: This may no longer be necessary since multi-tenant was removed.\n allowPartial: true, // required by server/runner/config.ts\n // Let the spawned zero-cache process emit deprecation warnings\n emitDeprecationWarnings: false,\n },\n );\n\n const lc = createLogContext(config);\n\n process.on('unhandledRejection', reason => {\n lc.error?.('Unexpected unhandled rejection.', reason);\n lc.error?.('Exiting');\n process.exit(-1);\n });\n\n // Parse options for each subprocess to get environment variables\n const {env: deployPermissionsEnv} = parseOptionsAdvanced(\n deployPermissionsOptions,\n {\n envNamePrefix: ZERO_ENV_VAR_PREFIX,\n allowUnknown: true,\n includeDefaults: false,\n emitDeprecationWarnings: false,\n },\n );\n const {env: zeroCacheEnv} = parseOptionsAdvanced(zeroOptions, {\n envNamePrefix: ZERO_ENV_VAR_PREFIX,\n allowUnknown: true,\n includeDefaults: false,\n emitDeprecationWarnings: false,\n });\n\n let permissionsProcess: ChildProcess | undefined;\n let zeroCacheProcess: ChildProcess | undefined;\n\n // Ensure child processes are killed when the main process exits\n process.on('exit', () => {\n permissionsProcess?.kill('SIGQUIT');\n zeroCacheProcess?.kill('SIGQUIT');\n });\n\n async function deployPermissions(): Promise<boolean> {\n if (config.upstream.type !== 'pg') {\n lc.warn?.(\n `Skipping permissions deployment for ${config.upstream.type} upstream`,\n );\n return true;\n }\n permissionsProcess?.removeAllListeners('exit');\n await killProcess(permissionsProcess);\n permissionsProcess = undefined;\n\n lc.info?.(`Running ${deployPermissionsScript}.`);\n permissionsProcess = spawn(deployPermissionsScript, [], {\n env: {...process.env, ...deployPermissionsEnv},\n stdio: 'inherit',\n shell: true,\n });\n\n const {promise: code, resolve} = resolver<number>();\n permissionsProcess.on('exit', resolve);\n if ((await code) === 0) {\n lc.info?.(`${deployPermissionsScript} completed successfully.`);\n return true;\n }\n lc.error?.(`Failed to deploy permissions from ${config.schema.path}.`);\n return false;\n }\n\n async function startZeroCache() {\n zeroCacheProcess?.removeAllListeners('exit');\n await killProcess(zeroCacheProcess);\n zeroCacheProcess = undefined;\n\n lc.info?.(\n `Running ${zeroCacheScript} at\\n\\n\\thttp://localhost:${config.port}\\n`,\n );\n const env: NodeJS.ProcessEnv = {\n // Set some low defaults so as to use fewer resources and not trip up,\n // e.g. developers sharing a database.\n ['ZERO_NUM_SYNC_WORKERS']: '3',\n ['ZERO_CVR_MAX_CONNS']: '6',\n ['ZERO_UPSTREAM_MAX_CONNS']: '6',\n\n // Default NODE_ENV to development mode.\n // @ts-ignore NODE_ENV is not always set. Please ignore error.\n ['NODE_ENV']: 'development',\n\n // But let the developer override any of these dev defaults.\n ...process.env,\n ...zeroCacheEnv,\n };\n zeroCacheProcess = spawn(zeroCacheScript, [], {\n env,\n stdio: 'inherit',\n shell: true,\n });\n zeroCacheProcess.on('exit', () => {\n lc.error?.(`${zeroCacheScript} exited. Exiting.`);\n process.exit(-1);\n });\n }\n\n async function deployPermissionsAndStartZeroCache() {\n if (await deployPermissions()) {\n await startZeroCache();\n }\n }\n\n if (config.schema.path) {\n if (config.query.url && config.mutate.url) {\n lc.warn?.(\n 'Using -p/--path/ZERO_SCHEMA_PATH with ZERO_MUTATE_URL and ZERO_QUERY_URL. ' +\n 'Continuing in hybrid mode: legacy permissions will still be deployed/watched, ' +\n 'and custom queries/mutations will use the API endpoints.',\n );\n }\n\n await deployPermissionsAndStartZeroCache();\n\n // Watch for file changes\n const watcher = watch(config.schema.path, {\n ignoreInitial: true,\n awaitWriteFinish: {stabilityThreshold: 500, pollInterval: 100},\n });\n const onFileChange = async () => {\n lc.info?.(`Detected ${config.schema.path} change.`);\n await deployPermissions();\n };\n watcher.on('add', onFileChange);\n watcher.on('change', onFileChange);\n watcher.on('unlink', onFileChange);\n } else {\n await startZeroCache();\n }\n}\n\nvoid main();\n"],"mappings":"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"}
1
+ {"version":3,"file":"zero-cache-dev.js","names":[],"sources":["../../../src/zero-cache-dev.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport '../../shared/src/dotenv.ts';\n\nimport {spawn, type ChildProcess} from 'node:child_process';\nimport {resolver} from '@rocicorp/resolver';\nimport {watch} from 'chokidar';\nimport {createLogContext} from '../../shared/src/logging.ts';\nimport {parseOptionsAdvanced} from '../../shared/src/options.ts';\nimport * as v from '../../shared/src/valita.ts';\nimport {\n ZERO_ENV_VAR_PREFIX,\n zeroOptions,\n} from '../../zero-cache/src/config/zero-config.ts';\nimport {deployPermissionsOptions} from '../../zero-cache/src/scripts/permissions.ts';\n\nconst deployPermissionsScript = 'zero-deploy-permissions';\nconst zeroCacheScript = 'zero-cache';\nconst startupMessageEnv = 'ZERO_ENABLE_STARTUP_MESSAGE';\n\nfunction killProcess(childProcess: ChildProcess | undefined) {\n if (!childProcess || childProcess.exitCode !== null) {\n return Promise.resolve();\n }\n const {resolve, promise} = resolver();\n childProcess.on('exit', resolve);\n // Use SIGQUIT in particular since this will cause\n // a fast zero-cache shutdown instead of a graceful drain.\n childProcess.kill('SIGQUIT');\n return promise;\n}\n\nasync function main() {\n const {config} = parseOptionsAdvanced(\n {\n schema: {\n path: {\n type: v.string().optional(),\n desc: ['Relative path to the file containing permissions.'],\n alias: 'p',\n deprecated: [\n 'Permissions are deprecated and will be removed in an upcoming release. See: https://zero.rocicorp.dev/docs/auth.',\n ],\n },\n },\n ...zeroOptions,\n },\n {\n envNamePrefix: ZERO_ENV_VAR_PREFIX,\n // TODO: This may no longer be necessary since multi-tenant was removed.\n allowPartial: true, // required by server/runner/config.ts\n // Let the spawned zero-cache process emit deprecation warnings\n emitDeprecationWarnings: false,\n },\n );\n\n const lc = createLogContext(config);\n\n process.on('unhandledRejection', reason => {\n lc.error?.('Unexpected unhandled rejection.', reason);\n lc.error?.('Exiting');\n process.exit(-1);\n });\n\n // Parse options for each subprocess to get environment variables\n const {env: deployPermissionsEnv} = parseOptionsAdvanced(\n deployPermissionsOptions,\n {\n envNamePrefix: ZERO_ENV_VAR_PREFIX,\n allowUnknown: true,\n includeDefaults: false,\n emitDeprecationWarnings: false,\n },\n );\n const {env: zeroCacheEnv} = parseOptionsAdvanced(zeroOptions, {\n envNamePrefix: ZERO_ENV_VAR_PREFIX,\n allowUnknown: true,\n includeDefaults: false,\n emitDeprecationWarnings: false,\n });\n\n let permissionsProcess: ChildProcess | undefined;\n let zeroCacheProcess: ChildProcess | undefined;\n\n // Ensure child processes are killed when the main process exits\n process.on('exit', () => {\n permissionsProcess?.kill('SIGQUIT');\n zeroCacheProcess?.kill('SIGQUIT');\n });\n\n async function deployPermissions(): Promise<boolean> {\n if (config.upstream.type !== 'pg') {\n lc.warn?.(\n `Skipping permissions deployment for ${config.upstream.type} upstream`,\n );\n return true;\n }\n permissionsProcess?.removeAllListeners('exit');\n await killProcess(permissionsProcess);\n permissionsProcess = undefined;\n\n lc.info?.(`Running ${deployPermissionsScript}.`);\n permissionsProcess = spawn(deployPermissionsScript, [], {\n env: {...process.env, ...deployPermissionsEnv},\n stdio: 'inherit',\n shell: true,\n });\n\n const {promise: code, resolve} = resolver<number>();\n permissionsProcess.on('exit', resolve);\n if ((await code) === 0) {\n lc.info?.(`${deployPermissionsScript} completed successfully.`);\n return true;\n }\n lc.error?.(`Failed to deploy permissions from ${config.schema.path}.`);\n return false;\n }\n\n async function startZeroCache() {\n zeroCacheProcess?.removeAllListeners('exit');\n await killProcess(zeroCacheProcess);\n zeroCacheProcess = undefined;\n\n lc.info?.(\n `Running ${zeroCacheScript} at\\n\\n\\thttp://localhost:${config.port}\\n`,\n );\n const env: NodeJS.ProcessEnv = {\n // Set some low defaults so as to use fewer resources and not trip up,\n // e.g. developers sharing a database.\n ['ZERO_NUM_SYNC_WORKERS']: '3',\n ['ZERO_CVR_MAX_CONNS']: '6',\n ['ZERO_UPSTREAM_MAX_CONNS']: '6',\n\n // Default NODE_ENV to development mode.\n // @ts-ignore NODE_ENV is not always set. Please ignore error.\n ['NODE_ENV']: 'development',\n\n // Print the dev-only startup message after the server is listening.\n [startupMessageEnv]: '1',\n\n // But let the developer override any of these dev defaults.\n ...process.env,\n ...zeroCacheEnv,\n };\n zeroCacheProcess = spawn(zeroCacheScript, [], {\n env,\n stdio: 'inherit',\n shell: true,\n });\n zeroCacheProcess.on('exit', () => {\n lc.error?.(`${zeroCacheScript} exited. Exiting.`);\n process.exit(-1);\n });\n }\n\n async function deployPermissionsAndStartZeroCache() {\n if (await deployPermissions()) {\n await startZeroCache();\n }\n }\n\n if (config.schema.path) {\n if (config.query.url && config.mutate.url) {\n lc.warn?.(\n 'Using -p/--path/ZERO_SCHEMA_PATH with ZERO_MUTATE_URL and ZERO_QUERY_URL. ' +\n 'Continuing in hybrid mode: legacy permissions will still be deployed/watched, ' +\n 'and custom queries/mutations will use the API endpoints.',\n );\n }\n\n await deployPermissionsAndStartZeroCache();\n\n // Watch for file changes\n const watcher = watch(config.schema.path, {\n ignoreInitial: true,\n awaitWriteFinish: {stabilityThreshold: 500, pollInterval: 100},\n });\n const onFileChange = async () => {\n lc.info?.(`Detected ${config.schema.path} change.`);\n await deployPermissions();\n };\n watcher.on('add', onFileChange);\n watcher.on('change', onFileChange);\n watcher.on('unlink', onFileChange);\n } else {\n await startZeroCache();\n }\n}\n\nvoid main();\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"run-worker.d.ts","sourceRoot":"","sources":["../../../../../../zero-cache/src/server/runner/run-worker.ts"],"names":[],"mappings":"AAAA,OAAO,kCAAkC,CAAC;AAO1C,OAAO,EAAc,KAAK,MAAM,EAAC,MAAM,0BAA0B,CAAC;AAMlE;;;;;;GAMG;AACH,wBAAsB,SAAS,CAC7B,MAAM,EAAE,MAAM,GAAG,IAAI,EACrB,GAAG,EAAE,MAAM,CAAC,UAAU,GACrB,OAAO,CAAC,IAAI,CAAC,CA0Df"}
1
+ {"version":3,"file":"run-worker.d.ts","sourceRoot":"","sources":["../../../../../../zero-cache/src/server/runner/run-worker.ts"],"names":[],"mappings":"AAAA,OAAO,kCAAkC,CAAC;AAS1C,OAAO,EAAc,KAAK,MAAM,EAAC,MAAM,0BAA0B,CAAC;AAsBlE;;;;;;GAMG;AACH,wBAAsB,SAAS,CAC7B,MAAM,EAAE,MAAM,GAAG,IAAI,EACrB,GAAG,EAAE,MAAM,CAAC,UAAU,GACrB,OAAO,CAAC,IAAI,CAAC,CA4Df"}
@@ -1,5 +1,6 @@
1
1
  import "../../../../zero-protocol/src/protocol-version.js";
2
2
  import "../../../../shared/src/dotenv.js";
3
+ import { colorConsole } from "../../../../shared/src/logging.js";
3
4
  import { childWorker } from "../../types/processes.js";
4
5
  import { normalizeZeroConfig } from "../../config/normalize.js";
5
6
  import { getServerVersion, getZeroConfig } from "../../config/zero-config.js";
@@ -9,7 +10,14 @@ import { MAIN_URL } from "../worker-urls.js";
9
10
  import { getTaskID } from "./runtime.js";
10
11
  import { ZeroDispatcher } from "./zero-dispatcher.js";
11
12
  import { resolver } from "@rocicorp/resolver";
13
+ import { styleText } from "node:util";
12
14
  //#region ../zero-cache/src/server/runner/run-worker.ts
15
+ var startupMessageEnv = "ZERO_ENABLE_STARTUP_MESSAGE";
16
+ function printStartupMessage(env) {
17
+ if (env[startupMessageEnv] !== "1") return;
18
+ colorConsole.log(`\nBTW, ${styleText(["bold", "cyan"], "Cloud Zero")} is now available - professional Zero hosting from the team that built it.
19
+ Get started now: ${styleText(["blue", "underline"], "https://zero.rocicorp.dev/cloud")}\n\n` + styleText("dim", `Disable this message with ${startupMessageEnv}=0`) + "\n");
20
+ }
13
21
  /**
14
22
  * Top-level `runner` entry point to the zero-cache. This layer is responsible for:
15
23
  * * runtime-based config normalization
@@ -52,7 +60,7 @@ async function runWorker(parent, env) {
52
60
  await processes.allWorkersReady();
53
61
  parent?.send(["ready", { ready: true }]);
54
62
  try {
55
- await runUntilKilled(lc, parent ?? process, new ZeroDispatcher(config, lc, { port }, startZeroCache));
63
+ await runUntilKilled(lc, parent ?? process, new ZeroDispatcher(config, lc, { port }, startZeroCache, () => printStartupMessage(env)));
56
64
  } catch (err) {
57
65
  processes.logErrorAndExit(err, "main");
58
66
  }
@@ -1 +1 @@
1
- {"version":3,"file":"run-worker.js","names":[],"sources":["../../../../../../zero-cache/src/server/runner/run-worker.ts"],"sourcesContent":["import '../../../../shared/src/dotenv.ts';\n\nimport {resolver, type Resolver} from '@rocicorp/resolver';\nimport {PROTOCOL_VERSION} from '../../../../zero-protocol/src/protocol-version.ts';\nimport {normalizeZeroConfig} from '../../config/normalize.ts';\nimport {getServerVersion, getZeroConfig} from '../../config/zero-config.ts';\nimport {ProcessManager, runUntilKilled} from '../../services/life-cycle.ts';\nimport {childWorker, type Worker} from '../../types/processes.ts';\nimport {createLogContext} from '../logging.ts';\nimport {MAIN_URL} from '../worker-urls.ts';\nimport {getTaskID} from './runtime.ts';\nimport {ZeroDispatcher} from './zero-dispatcher.ts';\n\n/**\n * Top-level `runner` entry point to the zero-cache. This layer is responsible for:\n * * runtime-based config normalization\n * * lazy startup\n * * serving /statsz\n * * auto-reset restarts (TODO)\n */\nexport async function runWorker(\n parent: Worker | null,\n env: NodeJS.ProcessEnv,\n): Promise<void> {\n // Note: Deprecation warnings are only emitted at this top-level parse;\n // they are suppressed when parsed in subprocesses.\n const cfg = getZeroConfig({env, emitDeprecationWarnings: true});\n const lc = createLogContext(cfg, 'runner');\n\n const defaultTaskID = await getTaskID(lc);\n const config = normalizeZeroConfig(lc, cfg, env, defaultTaskID);\n const processes = new ProcessManager(lc, parent ?? process);\n\n const {port, lazyStartup} = config;\n const serverVersion = getServerVersion(config);\n lc.info?.(`starting server${!serverVersion ? '' : `@${serverVersion}`} `, {\n protocolVersion: PROTOCOL_VERSION,\n taskID: config.taskID,\n app: config.app,\n shard: config.shard,\n port: config.port,\n });\n\n let zeroCache: Resolver<Worker> | undefined;\n function startZeroCache(): Promise<Worker> {\n if (zeroCache === undefined) {\n const startMs = performance.now();\n lc.info?.('starting zero-cache');\n\n const r = (zeroCache = resolver<Worker>());\n const w = childWorker(MAIN_URL, env)\n .once('message', () => {\n r.resolve(w);\n lc.info?.(`zero-cache ready (${performance.now() - startMs} ms)`);\n })\n .once('error', r.reject);\n\n processes.addWorker(w, 'user-facing', 'zero-cache');\n }\n return zeroCache.promise;\n }\n\n // Eagerly start the zero-cache if it was not configured with --lazy-startup.\n if (!lazyStartup) {\n void startZeroCache();\n }\n\n await processes.allWorkersReady();\n parent?.send(['ready', {ready: true}]);\n\n try {\n await runUntilKilled(\n lc,\n parent ?? process,\n new ZeroDispatcher(config, lc, {port}, startZeroCache),\n );\n } catch (err) {\n processes.logErrorAndExit(err, 'main');\n }\n\n await processes.done();\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAoBA,eAAsB,UACpB,QACA,KACe;CAGf,MAAM,MAAM,cAAc;EAAC;EAAK,yBAAyB;EAAK,CAAC;CAC/D,MAAM,KAAK,iBAAiB,KAAK,SAAS;CAG1C,MAAM,SAAS,oBAAoB,IAAI,KAAK,KADtB,MAAM,UAAU,GAAG,CACsB;CAC/D,MAAM,YAAY,IAAI,eAAe,IAAI,UAAU,QAAQ;CAE3D,MAAM,EAAC,MAAM,gBAAe;CAC5B,MAAM,gBAAgB,iBAAiB,OAAO;AAC9C,IAAG,OAAO,kBAAkB,CAAC,gBAAgB,KAAK,IAAI,gBAAgB,IAAI;EACxE,iBAAA;EACA,QAAQ,OAAO;EACf,KAAK,OAAO;EACZ,OAAO,OAAO;EACd,MAAM,OAAO;EACd,CAAC;CAEF,IAAI;CACJ,SAAS,iBAAkC;AACzC,MAAI,cAAc,KAAA,GAAW;GAC3B,MAAM,UAAU,YAAY,KAAK;AACjC,MAAG,OAAO,sBAAsB;GAEhC,MAAM,IAAK,YAAY,UAAkB;GACzC,MAAM,IAAI,YAAY,UAAU,IAAI,CACjC,KAAK,iBAAiB;AACrB,MAAE,QAAQ,EAAE;AACZ,OAAG,OAAO,qBAAqB,YAAY,KAAK,GAAG,QAAQ,MAAM;KACjE,CACD,KAAK,SAAS,EAAE,OAAO;AAE1B,aAAU,UAAU,GAAG,eAAe,aAAa;;AAErD,SAAO,UAAU;;AAInB,KAAI,CAAC,YACE,iBAAgB;AAGvB,OAAM,UAAU,iBAAiB;AACjC,SAAQ,KAAK,CAAC,SAAS,EAAC,OAAO,MAAK,CAAC,CAAC;AAEtC,KAAI;AACF,QAAM,eACJ,IACA,UAAU,SACV,IAAI,eAAe,QAAQ,IAAI,EAAC,MAAK,EAAE,eAAe,CACvD;UACM,KAAK;AACZ,YAAU,gBAAgB,KAAK,OAAO;;AAGxC,OAAM,UAAU,MAAM"}
1
+ {"version":3,"file":"run-worker.js","names":[],"sources":["../../../../../../zero-cache/src/server/runner/run-worker.ts"],"sourcesContent":["import '../../../../shared/src/dotenv.ts';\n\nimport {styleText} from 'node:util';\nimport {resolver, type Resolver} from '@rocicorp/resolver';\nimport {colorConsole} from '../../../../shared/src/logging.ts';\nimport {PROTOCOL_VERSION} from '../../../../zero-protocol/src/protocol-version.ts';\nimport {normalizeZeroConfig} from '../../config/normalize.ts';\nimport {getServerVersion, getZeroConfig} from '../../config/zero-config.ts';\nimport {ProcessManager, runUntilKilled} from '../../services/life-cycle.ts';\nimport {childWorker, type Worker} from '../../types/processes.ts';\nimport {createLogContext} from '../logging.ts';\nimport {MAIN_URL} from '../worker-urls.ts';\nimport {getTaskID} from './runtime.ts';\nimport {ZeroDispatcher} from './zero-dispatcher.ts';\n\nconst startupMessageEnv = 'ZERO_ENABLE_STARTUP_MESSAGE';\n\nfunction printStartupMessage(env: NodeJS.ProcessEnv) {\n if (env[startupMessageEnv] !== '1') {\n return;\n }\n\n colorConsole.log(\n `\\nBTW, ${styleText(['bold', 'cyan'], 'Cloud Zero')} ` +\n 'is now available - professional Zero hosting from the team that built it.\\n' +\n `Get started now: ${styleText(['blue', 'underline'], 'https://zero.rocicorp.dev/cloud')}\\n\\n` +\n styleText('dim', `Disable this message with ${startupMessageEnv}=0`) +\n '\\n',\n );\n}\n\n/**\n * Top-level `runner` entry point to the zero-cache. This layer is responsible for:\n * * runtime-based config normalization\n * * lazy startup\n * * serving /statsz\n * * auto-reset restarts (TODO)\n */\nexport async function runWorker(\n parent: Worker | null,\n env: NodeJS.ProcessEnv,\n): Promise<void> {\n // Note: Deprecation warnings are only emitted at this top-level parse;\n // they are suppressed when parsed in subprocesses.\n const cfg = getZeroConfig({env, emitDeprecationWarnings: true});\n const lc = createLogContext(cfg, 'runner');\n\n const defaultTaskID = await getTaskID(lc);\n const config = normalizeZeroConfig(lc, cfg, env, defaultTaskID);\n const processes = new ProcessManager(lc, parent ?? process);\n\n const {port, lazyStartup} = config;\n const serverVersion = getServerVersion(config);\n lc.info?.(`starting server${!serverVersion ? '' : `@${serverVersion}`} `, {\n protocolVersion: PROTOCOL_VERSION,\n taskID: config.taskID,\n app: config.app,\n shard: config.shard,\n port: config.port,\n });\n\n let zeroCache: Resolver<Worker> | undefined;\n function startZeroCache(): Promise<Worker> {\n if (zeroCache === undefined) {\n const startMs = performance.now();\n lc.info?.('starting zero-cache');\n\n const r = (zeroCache = resolver<Worker>());\n const w = childWorker(MAIN_URL, env)\n .once('message', () => {\n r.resolve(w);\n lc.info?.(`zero-cache ready (${performance.now() - startMs} ms)`);\n })\n .once('error', r.reject);\n\n processes.addWorker(w, 'user-facing', 'zero-cache');\n }\n return zeroCache.promise;\n }\n\n // Eagerly start the zero-cache if it was not configured with --lazy-startup.\n if (!lazyStartup) {\n void startZeroCache();\n }\n\n await processes.allWorkersReady();\n parent?.send(['ready', {ready: true}]);\n\n try {\n await runUntilKilled(\n lc,\n parent ?? process,\n new ZeroDispatcher(config, lc, {port}, startZeroCache, () =>\n printStartupMessage(env),\n ),\n );\n } catch (err) {\n processes.logErrorAndExit(err, 'main');\n }\n\n await processes.done();\n}\n"],"mappings":";;;;;;;;;;;;;;AAeA,IAAM,oBAAoB;AAE1B,SAAS,oBAAoB,KAAwB;AACnD,KAAI,IAAI,uBAAuB,IAC7B;AAGF,cAAa,IACX,UAAU,UAAU,CAAC,QAAQ,OAAO,EAAE,aAAa,CAAC;mBAE9B,UAAU,CAAC,QAAQ,YAAY,EAAE,kCAAkC,CAAC,QACxF,UAAU,OAAO,6BAA6B,kBAAkB,IAAI,GACpE,KACH;;;;;;;;;AAUH,eAAsB,UACpB,QACA,KACe;CAGf,MAAM,MAAM,cAAc;EAAC;EAAK,yBAAyB;EAAK,CAAC;CAC/D,MAAM,KAAK,iBAAiB,KAAK,SAAS;CAG1C,MAAM,SAAS,oBAAoB,IAAI,KAAK,KADtB,MAAM,UAAU,GAAG,CACsB;CAC/D,MAAM,YAAY,IAAI,eAAe,IAAI,UAAU,QAAQ;CAE3D,MAAM,EAAC,MAAM,gBAAe;CAC5B,MAAM,gBAAgB,iBAAiB,OAAO;AAC9C,IAAG,OAAO,kBAAkB,CAAC,gBAAgB,KAAK,IAAI,gBAAgB,IAAI;EACxE,iBAAA;EACA,QAAQ,OAAO;EACf,KAAK,OAAO;EACZ,OAAO,OAAO;EACd,MAAM,OAAO;EACd,CAAC;CAEF,IAAI;CACJ,SAAS,iBAAkC;AACzC,MAAI,cAAc,KAAA,GAAW;GAC3B,MAAM,UAAU,YAAY,KAAK;AACjC,MAAG,OAAO,sBAAsB;GAEhC,MAAM,IAAK,YAAY,UAAkB;GACzC,MAAM,IAAI,YAAY,UAAU,IAAI,CACjC,KAAK,iBAAiB;AACrB,MAAE,QAAQ,EAAE;AACZ,OAAG,OAAO,qBAAqB,YAAY,KAAK,GAAG,QAAQ,MAAM;KACjE,CACD,KAAK,SAAS,EAAE,OAAO;AAE1B,aAAU,UAAU,GAAG,eAAe,aAAa;;AAErD,SAAO,UAAU;;AAInB,KAAI,CAAC,YACE,iBAAgB;AAGvB,OAAM,UAAU,iBAAiB;AACjC,SAAQ,KAAK,CAAC,SAAS,EAAC,OAAO,MAAK,CAAC,CAAC;AAEtC,KAAI;AACF,QAAM,eACJ,IACA,UAAU,SACV,IAAI,eAAe,QAAQ,IAAI,EAAC,MAAK,EAAE,sBACrC,oBAAoB,IAAI,CACzB,CACF;UACM,KAAK;AACZ,YAAU,gBAAgB,KAAK,OAAO;;AAGxC,OAAM,UAAU,MAAM"}
@@ -5,6 +5,7 @@ import type { Worker } from '../../types/processes.ts';
5
5
  export declare class ZeroDispatcher extends HttpService {
6
6
  #private;
7
7
  readonly id = "zero-dispatcher";
8
- constructor(config: NormalizedZeroConfig, lc: LogContext, opts: Options, getWorker: () => Promise<Worker>);
8
+ constructor(config: NormalizedZeroConfig, lc: LogContext, opts: Options, getWorker: () => Promise<Worker>, onStart?: () => void);
9
+ protected _onStart(): void;
9
10
  }
10
11
  //# sourceMappingURL=zero-dispatcher.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"zero-dispatcher.d.ts","sourceRoot":"","sources":["../../../../../../zero-cache/src/server/runner/zero-dispatcher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AACjD,OAAO,KAAK,EAAC,oBAAoB,EAAC,MAAM,2BAA2B,CAAC;AAEpE,OAAO,EAAC,WAAW,EAAE,KAAK,OAAO,EAAC,MAAM,gCAAgC,CAAC;AAGzE,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,0BAA0B,CAAC;AAMrD,qBAAa,cAAe,SAAQ,WAAW;;IAC7C,QAAQ,CAAC,EAAE,qBAAqB;gBAI9B,MAAM,EAAE,oBAAoB,EAC5B,EAAE,EAAE,UAAU,EACd,IAAI,EAAE,OAAO,EACb,SAAS,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC;CAwBnC"}
1
+ {"version":3,"file":"zero-dispatcher.d.ts","sourceRoot":"","sources":["../../../../../../zero-cache/src/server/runner/zero-dispatcher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AACjD,OAAO,KAAK,EAAC,oBAAoB,EAAC,MAAM,2BAA2B,CAAC;AAEpE,OAAO,EAAC,WAAW,EAAE,KAAK,OAAO,EAAC,MAAM,gCAAgC,CAAC;AAGzE,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,0BAA0B,CAAC;AAMrD,qBAAa,cAAe,SAAQ,WAAW;;IAC7C,QAAQ,CAAC,EAAE,qBAAqB;gBAK9B,MAAM,EAAE,oBAAoB,EAC5B,EAAE,EAAE,UAAU,EACd,IAAI,EAAE,OAAO,EACb,SAAS,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,EAChC,OAAO,CAAC,EAAE,MAAM,IAAI;cAeH,QAAQ;CAc5B"}
@@ -6,13 +6,18 @@ import { installWebSocketHandoff } from "../../types/websocket-handoff.js";
6
6
  var ZeroDispatcher = class extends HttpService {
7
7
  id = "zero-dispatcher";
8
8
  #getWorker;
9
- constructor(config, lc, opts, getWorker) {
9
+ #onStart;
10
+ constructor(config, lc, opts, getWorker, onStart) {
10
11
  super(`zero-dispatcher`, lc, opts, (fastify) => {
11
12
  fastify.get("/statz", (req, res) => handleStatzRequest(lc, config, req, res));
12
13
  fastify.get("/heapz", (req, res) => handleHeapzRequest(lc, config, req, res));
13
14
  installWebSocketHandoff(lc, this.#handoff, fastify.server);
14
15
  });
15
16
  this.#getWorker = getWorker;
17
+ this.#onStart = onStart;
18
+ }
19
+ _onStart() {
20
+ this.#onStart?.();
16
21
  }
17
22
  #handoff = (_req, dispatch, onError) => {
18
23
  this.#getWorker().then((sender) => dispatch({
@@ -1 +1 @@
1
- {"version":3,"file":"zero-dispatcher.js","names":["#getWorker","#handoff"],"sources":["../../../../../../zero-cache/src/server/runner/zero-dispatcher.ts"],"sourcesContent":["import type {LogContext} from '@rocicorp/logger';\nimport type {NormalizedZeroConfig} from '../../config/normalize.ts';\nimport {handleHeapzRequest} from '../../services/heapz.ts';\nimport {HttpService, type Options} from '../../services/http-service.ts';\nimport {handleStatzRequest} from '../../services/statz.ts';\nimport type {IncomingMessageSubset} from '../../types/http.ts';\nimport type {Worker} from '../../types/processes.ts';\nimport {\n installWebSocketHandoff,\n type HandoffSpec,\n} from '../../types/websocket-handoff.ts';\n\nexport class ZeroDispatcher extends HttpService {\n readonly id = 'zero-dispatcher';\n readonly #getWorker: () => Promise<Worker>;\n\n constructor(\n config: NormalizedZeroConfig,\n lc: LogContext,\n opts: Options,\n getWorker: () => Promise<Worker>,\n ) {\n super(`zero-dispatcher`, lc, opts, fastify => {\n fastify.get('/statz', (req, res) =>\n handleStatzRequest(lc, config, req, res),\n );\n fastify.get('/heapz', (req, res) =>\n handleHeapzRequest(lc, config, req, res),\n );\n installWebSocketHandoff(lc, this.#handoff, fastify.server);\n });\n this.#getWorker = getWorker;\n }\n\n readonly #handoff = (\n _req: IncomingMessageSubset,\n dispatch: (h: HandoffSpec<string>) => void,\n onError: (error: unknown) => void,\n ) => {\n void this.#getWorker().then(\n sender => dispatch({payload: 'unused', sender}),\n onError,\n );\n };\n}\n"],"mappings":";;;;;AAYA,IAAa,iBAAb,cAAoC,YAAY;CAC9C,KAAc;CACd;CAEA,YACE,QACA,IACA,MACA,WACA;AACA,QAAM,mBAAmB,IAAI,OAAM,YAAW;AAC5C,WAAQ,IAAI,WAAW,KAAK,QAC1B,mBAAmB,IAAI,QAAQ,KAAK,IAAI,CACzC;AACD,WAAQ,IAAI,WAAW,KAAK,QAC1B,mBAAmB,IAAI,QAAQ,KAAK,IAAI,CACzC;AACD,2BAAwB,IAAI,MAAA,SAAe,QAAQ,OAAO;IAC1D;AACF,QAAA,YAAkB;;CAGpB,YACE,MACA,UACA,YACG;AACE,QAAA,WAAiB,CAAC,MACrB,WAAU,SAAS;GAAC,SAAS;GAAU;GAAO,CAAC,EAC/C,QACD"}
1
+ {"version":3,"file":"zero-dispatcher.js","names":["#getWorker","#onStart","#handoff"],"sources":["../../../../../../zero-cache/src/server/runner/zero-dispatcher.ts"],"sourcesContent":["import type {LogContext} from '@rocicorp/logger';\nimport type {NormalizedZeroConfig} from '../../config/normalize.ts';\nimport {handleHeapzRequest} from '../../services/heapz.ts';\nimport {HttpService, type Options} from '../../services/http-service.ts';\nimport {handleStatzRequest} from '../../services/statz.ts';\nimport type {IncomingMessageSubset} from '../../types/http.ts';\nimport type {Worker} from '../../types/processes.ts';\nimport {\n installWebSocketHandoff,\n type HandoffSpec,\n} from '../../types/websocket-handoff.ts';\n\nexport class ZeroDispatcher extends HttpService {\n readonly id = 'zero-dispatcher';\n readonly #getWorker: () => Promise<Worker>;\n readonly #onStart: (() => void) | undefined;\n\n constructor(\n config: NormalizedZeroConfig,\n lc: LogContext,\n opts: Options,\n getWorker: () => Promise<Worker>,\n onStart?: () => void,\n ) {\n super(`zero-dispatcher`, lc, opts, fastify => {\n fastify.get('/statz', (req, res) =>\n handleStatzRequest(lc, config, req, res),\n );\n fastify.get('/heapz', (req, res) =>\n handleHeapzRequest(lc, config, req, res),\n );\n installWebSocketHandoff(lc, this.#handoff, fastify.server);\n });\n this.#getWorker = getWorker;\n this.#onStart = onStart;\n }\n\n protected override _onStart() {\n this.#onStart?.();\n }\n\n readonly #handoff = (\n _req: IncomingMessageSubset,\n dispatch: (h: HandoffSpec<string>) => void,\n onError: (error: unknown) => void,\n ) => {\n void this.#getWorker().then(\n sender => dispatch({payload: 'unused', sender}),\n onError,\n );\n };\n}\n"],"mappings":";;;;;AAYA,IAAa,iBAAb,cAAoC,YAAY;CAC9C,KAAc;CACd;CACA;CAEA,YACE,QACA,IACA,MACA,WACA,SACA;AACA,QAAM,mBAAmB,IAAI,OAAM,YAAW;AAC5C,WAAQ,IAAI,WAAW,KAAK,QAC1B,mBAAmB,IAAI,QAAQ,KAAK,IAAI,CACzC;AACD,WAAQ,IAAI,WAAW,KAAK,QAC1B,mBAAmB,IAAI,QAAQ,KAAK,IAAI,CACzC;AACD,2BAAwB,IAAI,MAAA,SAAe,QAAQ,OAAO;IAC1D;AACF,QAAA,YAAkB;AAClB,QAAA,UAAgB;;CAGlB,WAA8B;AAC5B,QAAA,WAAiB;;CAGnB,YACE,MACA,UACA,YACG;AACE,QAAA,WAAiB,CAAC,MACrB,WAAU,SAAS;GAAC,SAAS;GAAU;GAAO,CAAC,EAC/C,QACD"}
@@ -2,7 +2,7 @@
2
2
  /**
3
3
  * The current version of Zero.
4
4
  */
5
- var version = "1.4.0-canary.3";
5
+ var version = "1.4.0-canary.4";
6
6
  //#endregion
7
7
  export { version };
8
8
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rocicorp/zero",
3
- "version": "1.4.0-canary.3",
3
+ "version": "1.4.0-canary.4",
4
4
  "description": "Zero is a web framework for serverless web development.",
5
5
  "homepage": "https://zero.rocicorp.dev",
6
6
  "bugs": {