bunderstack 0.25.1 → 1.0.0-beta.1
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/CHANGELOG.md +43 -0
- package/dist/auth-password.d.ts +27 -0
- package/dist/auth-password.d.ts.map +1 -0
- package/dist/auth-password.js +60 -0
- package/dist/auth-password.js.map +1 -0
- package/dist/auth.d.ts +1 -1
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +1 -0
- package/dist/auth.js.map +1 -1
- package/dist/backend.d.ts +3 -0
- package/dist/backend.d.ts.map +1 -1
- package/dist/backend.js +3 -1
- package/dist/backend.js.map +1 -1
- package/dist/cli.d.ts +11 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +97 -2
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +0 -8
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +0 -18
- package/dist/config.js.map +1 -1
- package/dist/crud-operations.d.ts.map +1 -1
- package/dist/crud-operations.js +19 -3
- package/dist/crud-operations.js.map +1 -1
- package/dist/dev/binaries.d.ts +22 -0
- package/dist/dev/binaries.d.ts.map +1 -0
- package/dist/dev/binaries.js +119 -0
- package/dist/dev/binaries.js.map +1 -0
- package/dist/dev/env.d.ts +11 -0
- package/dist/dev/env.d.ts.map +1 -0
- package/dist/dev/env.js +71 -0
- package/dist/dev/env.js.map +1 -0
- package/dist/dev/index.d.ts +45 -0
- package/dist/dev/index.d.ts.map +1 -0
- package/dist/dev/index.js +287 -0
- package/dist/dev/index.js.map +1 -0
- package/dist/dev/processes.d.ts +37 -0
- package/dist/dev/processes.d.ts.map +1 -0
- package/dist/dev/processes.js +104 -0
- package/dist/dev/processes.js.map +1 -0
- package/dist/dev/push.d.ts +2 -0
- package/dist/dev/push.d.ts.map +1 -0
- package/dist/dev/push.js +25 -0
- package/dist/dev/push.js.map +1 -0
- package/dist/env-probe.d.ts.map +1 -1
- package/dist/env-probe.js +0 -1
- package/dist/env-probe.js.map +1 -1
- package/dist/env.d.ts +0 -3
- package/dist/env.d.ts.map +1 -1
- package/dist/env.js +0 -7
- package/dist/env.js.map +1 -1
- package/dist/handler.d.ts +2 -0
- package/dist/handler.d.ts.map +1 -1
- package/dist/handler.js +1 -2
- package/dist/handler.js.map +1 -1
- package/dist/hosted-contract.d.ts.map +1 -1
- package/dist/hosted-contract.js +7 -3
- package/dist/hosted-contract.js.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/jobs/define.d.ts +5 -0
- package/dist/jobs/define.d.ts.map +1 -1
- package/dist/jobs/define.js.map +1 -1
- package/dist/jobs/index.d.ts +2 -4
- package/dist/jobs/index.d.ts.map +1 -1
- package/dist/jobs/index.js +2 -3
- package/dist/jobs/index.js.map +1 -1
- package/dist/jobs/queue.d.ts +1 -0
- package/dist/jobs/queue.d.ts.map +1 -1
- package/dist/jobs/queue.js +6 -3
- package/dist/jobs/queue.js.map +1 -1
- package/dist/jobs/slots.d.ts +5 -0
- package/dist/jobs/slots.d.ts.map +1 -1
- package/dist/jobs/slots.js +12 -0
- package/dist/jobs/slots.js.map +1 -1
- package/dist/jobs/worker.d.ts +6 -0
- package/dist/jobs/worker.d.ts.map +1 -1
- package/dist/jobs/worker.js +32 -1
- package/dist/jobs/worker.js.map +1 -1
- package/dist/platform.d.ts +25 -0
- package/dist/platform.d.ts.map +1 -0
- package/dist/platform.js +24 -0
- package/dist/platform.js.map +1 -0
- package/dist/query/client.js +1 -1
- package/dist/query/client.js.map +1 -1
- package/dist/rate-limit.d.ts +2 -1
- package/dist/rate-limit.d.ts.map +1 -1
- package/dist/rate-limit.js +19 -22
- package/dist/rate-limit.js.map +1 -1
- package/dist/realtime/facade.d.ts +1 -1
- package/dist/realtime/facade.d.ts.map +1 -1
- package/dist/realtime/facade.js.map +1 -1
- package/dist/realtime/publisher.d.ts +0 -4
- package/dist/realtime/publisher.d.ts.map +1 -1
- package/dist/realtime/publisher.js +0 -9
- package/dist/realtime/publisher.js.map +1 -1
- package/dist/runtime.d.ts +5 -19
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +28 -102
- package/dist/runtime.js.map +1 -1
- package/dist/storage/registry.d.ts +2 -1
- package/dist/storage/registry.d.ts.map +1 -1
- package/dist/storage/registry.js +2 -2
- package/dist/storage/registry.js.map +1 -1
- package/dist/storage/s3.d.ts +11 -4
- package/dist/storage/s3.d.ts.map +1 -1
- package/dist/storage/s3.js +88 -34
- package/dist/storage/s3.js.map +1 -1
- package/dist/storage/sigv4.d.ts +24 -0
- package/dist/storage/sigv4.d.ts.map +1 -0
- package/dist/storage/sigv4.js +107 -0
- package/dist/storage/sigv4.js.map +1 -0
- package/dist/testing/fixture.d.ts.map +1 -1
- package/dist/testing/fixture.js +0 -3
- package/dist/testing/fixture.js.map +1 -1
- package/dist/testing/workers-fakes.d.ts +17 -0
- package/dist/testing/workers-fakes.d.ts.map +1 -0
- package/dist/testing/workers-fakes.js +98 -0
- package/dist/testing/workers-fakes.js.map +1 -0
- package/dist/typeid.d.ts +1 -0
- package/dist/typeid.d.ts.map +1 -1
- package/dist/typeid.js +34 -4
- package/dist/typeid.js.map +1 -1
- package/dist/vite.d.ts +30 -0
- package/dist/vite.d.ts.map +1 -0
- package/dist/vite.js +37 -0
- package/dist/vite.js.map +1 -0
- package/dist/workers/app.d.ts +19 -0
- package/dist/workers/app.d.ts.map +1 -0
- package/dist/workers/app.js +56 -0
- package/dist/workers/app.js.map +1 -0
- package/dist/workers/index.d.ts +21 -0
- package/dist/workers/index.d.ts.map +1 -0
- package/dist/workers/index.js +33 -0
- package/dist/workers/index.js.map +1 -0
- package/dist/workers/r2.d.ts +23 -0
- package/dist/workers/r2.d.ts.map +1 -0
- package/dist/workers/r2.js +77 -0
- package/dist/workers/r2.js.map +1 -0
- package/dist/workers/rate-limiter.d.ts +9 -0
- package/dist/workers/rate-limiter.d.ts.map +1 -0
- package/dist/workers/rate-limiter.js +22 -0
- package/dist/workers/rate-limiter.js.map +1 -0
- package/dist/workers/realtime-hub.d.ts +20 -0
- package/dist/workers/realtime-hub.d.ts.map +1 -0
- package/dist/workers/realtime-hub.js +117 -0
- package/dist/workers/realtime-hub.js.map +1 -0
- package/dist/workers/scheduler.d.ts +13 -0
- package/dist/workers/scheduler.d.ts.map +1 -0
- package/dist/workers/scheduler.js +71 -0
- package/dist/workers/scheduler.js.map +1 -0
- package/dist/workers/types.d.ts +55 -0
- package/dist/workers/types.d.ts.map +1 -0
- package/dist/workers/types.js +4 -0
- package/dist/workers/types.js.map +1 -0
- package/dist/workers/wrangler.d.ts +64 -0
- package/dist/workers/wrangler.d.ts.map +1 -0
- package/dist/workers/wrangler.js +115 -0
- package/dist/workers/wrangler.js.map +1 -0
- package/llms-full.txt +10 -1
- package/package.json +11 -3
- package/dist/jobs/runtime.d.ts +0 -17
- package/dist/jobs/runtime.d.ts.map +0 -1
- package/dist/jobs/runtime.js +0 -56
- package/dist/jobs/runtime.js.map +0 -1
package/dist/env.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"env.js","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"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","sourcesContent":["// src/env.ts — env validation. Browser-safe: type-only Standard Schema import.\nimport type { StandardSchemaV1 } from '@standard-schema/spec'\n\nimport {\n StandardSchemaValidationError,\n validateStandardSchema,\n} from './standard-schema'\n\nexport const CLIENT_PREFIX = 'PUBLIC_' as const\n\n/**\n * Static, value-free metadata about an environment key. It reaches the manifest\n * and the committed blueprint, so it must never contain a value or a secret.\n */\nexport type EnvVarMeta = {\n /**\n * Whether the value is a secret. Defaults to `true` for server keys and\n * `false` for client keys. A client key can never be sensitive: `PUBLIC_*`\n * values are compiled into the browser bundle.\n */\n sensitive?: boolean\n /** Prose shown to whoever fills this key in. Max 200 characters. */\n description?: string\n}\n\nexport type EnvConfigInput = {\n server?: Record<string, StandardSchemaV1>\n client?: Record<string, StandardSchemaV1>\n /** Explicit value source for client vars (e.g. Vite's import.meta.env). */\n runtimeEnv?: Record<string, unknown>\n /** Value-free metadata per key, keyed by the key's own name. */\n meta?: Record<string, EnvVarMeta>\n}\n\nexport type BunderstackRole = 'all' | 'web' | 'worker'\n\nconst ROLES: readonly BunderstackRole[] = ['all', 'web', 'worker']\n\n/** Vars bunderstack itself consumes, always validated. */\nexport type BaseEnv = {\n NODE_ENV?: string\n DATABASE_URL: string\n DATABASE_AUTH_TOKEN?: string\n AUTH_SECRET: string\n REDIS_URL?: string\n RESEND_API_KEY?: string\n BUNDERSTACK_MESSAGING_CONFIG?: string\n BUNDERSTACK_BLUEPRINT_PATH?: string\n BUNDERHOST_ENVIRONMENT_ID?: string\n /** Deployed commit SHA, injected by the platform. Reported by readiness. */\n BUNDERSTACK_REVISION?: string\n BUNDERSTACK_ROLE: BunderstackRole\n}\n\ntype InferVars<T> =\n T extends Record<string, StandardSchemaV1>\n ? { [K in keyof T]: StandardSchemaV1.InferOutput<T[K]> }\n : unknown\n\n// Non-distributive so `ValidatedEnv<undefined>` is BaseEnv, not `never`.\nexport type ValidatedEnv<TEnv extends EnvConfigInput | undefined> = [\n TEnv,\n] extends [EnvConfigInput]\n ? BaseEnv &\n InferVars<NonNullable<TEnv>['server']> &\n InferVars<NonNullable<TEnv>['client']>\n : BaseEnv\n\nexport class BunderstackEnvError extends Error {\n readonly issues: string[]\n\n constructor(issues: string[]) {\n super(`Invalid environment:\\n - ${issues.join('\\n - ')}`)\n this.name = 'BunderstackEnvError'\n this.issues = issues\n }\n}\n\nexport type ValidateEnvOptions = {\n /** Value source; defaults to process.env. Tests pass this explicitly. */\n source?: Record<string, string | undefined>\n /** Dialect-aware DATABASE_URL fallback; bunderstack passes it. */\n defaultDatabaseUrl?: string\n}\n\nconst DEV_AUTH_SECRET = 'dev-secret-change-in-prod'\n\nfunction validateSection(\n section: Record<string, StandardSchemaV1> | undefined,\n kind: 'server' | 'client',\n source: Record<string, unknown>,\n issues: string[],\n out: Record<string, unknown>,\n) {\n for (const [key, schema] of Object.entries(section ?? {})) {\n const isPublic = key.startsWith(CLIENT_PREFIX)\n if (kind === 'server' && isPublic) {\n issues.push(\n `${key}: server vars must not start with ${CLIENT_PREFIX} (move it to env.client)`,\n )\n continue\n }\n if (kind === 'client' && !isPublic) {\n issues.push(\n `${key}: client vars must start with ${CLIENT_PREFIX} (rename it or move it to env.server)`,\n )\n continue\n }\n try {\n out[key] = validateStandardSchema(schema, source[key], 'env')\n } catch (error) {\n if (!(error instanceof StandardSchemaValidationError)) throw error\n for (const issue of error.issues) {\n const path = issue.path.map(String).join('.')\n issues.push(`${key}${path ? `.${path}` : ''}: ${issue.message}`)\n }\n }\n }\n}\n\nexport function validateEnv<TEnv extends EnvConfigInput | undefined>(\n envConfig: TEnv,\n options: ValidateEnvOptions = {},\n): ValidatedEnv<TEnv> {\n const source =\n options.source ?? (process.env as Record<string, string | undefined>)\n const issues: string[] = []\n const isProduction = source.NODE_ENV === 'production'\n\n const base: BaseEnv = {\n NODE_ENV: source.NODE_ENV,\n DATABASE_URL:\n source.DATABASE_URL ?? options.defaultDatabaseUrl ?? 'file:./data.db',\n DATABASE_AUTH_TOKEN: source.DATABASE_AUTH_TOKEN,\n AUTH_SECRET: source.AUTH_SECRET ?? DEV_AUTH_SECRET,\n REDIS_URL: source.REDIS_URL,\n RESEND_API_KEY: source.RESEND_API_KEY,\n BUNDERSTACK_MESSAGING_CONFIG: source.BUNDERSTACK_MESSAGING_CONFIG,\n BUNDERSTACK_BLUEPRINT_PATH: source.BUNDERSTACK_BLUEPRINT_PATH,\n BUNDERHOST_ENVIRONMENT_ID: source.BUNDERHOST_ENVIRONMENT_ID,\n BUNDERSTACK_REVISION: source.BUNDERSTACK_REVISION,\n BUNDERSTACK_ROLE: (source.BUNDERSTACK_ROLE ?? 'all') as BunderstackRole,\n }\n if (isProduction && !source.AUTH_SECRET) {\n issues.push('AUTH_SECRET: required in production')\n }\n if (\n source.BUNDERSTACK_ROLE !== undefined &&\n !ROLES.includes(source.BUNDERSTACK_ROLE as BunderstackRole)\n ) {\n issues.push(\n `BUNDERSTACK_ROLE: must be one of ${ROLES.join(', ')} (got \"${String(source.BUNDERSTACK_ROLE)}\")`,\n )\n }\n const userVars: Record<string, unknown> = {}\n validateSection(envConfig?.server, 'server', source, issues, userVars)\n validateSection(envConfig?.client, 'client', source, issues, userVars)\n\n if (issues.length > 0) throw new BunderstackEnvError(issues)\n return { ...base, ...userVars } as ValidatedEnv<TEnv>\n}\n\n/**\n * Browser-side companion (t3-env style): validates ONLY the client section.\n * Server keys exist on the returned object as traps that throw on access, so\n * a leaked import fails loudly instead of silently reading undefined.\n */\nexport function createClientEnv<TEnv extends EnvConfigInput>(\n envConfig: TEnv,\n): InferVars<TEnv['client']> {\n const source =\n envConfig.runtimeEnv ??\n (typeof process !== 'undefined'\n ? (process.env as Record<string, unknown>)\n : {})\n const issues: string[] = []\n const values: Record<string, unknown> = {}\n validateSection(envConfig.client, 'client', source, issues, values)\n if (issues.length > 0) throw new BunderstackEnvError(issues)\n\n const serverKeys = new Set(Object.keys(envConfig.server ?? {}))\n return new Proxy(values, {\n get(target, prop) {\n if (typeof prop === 'string' && serverKeys.has(prop)) {\n throw new Error(\n `${prop} is server-only and not available in client env`,\n )\n }\n return Reflect.get(target, prop)\n },\n }) as InferVars<TEnv['client']>\n}\n"]}
|
|
1
|
+
{"version":3,"file":"env.js","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"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","sourcesContent":["// src/env.ts — env validation. Browser-safe: type-only Standard Schema import.\nimport type { StandardSchemaV1 } from '@standard-schema/spec'\n\nimport {\n StandardSchemaValidationError,\n validateStandardSchema,\n} from './standard-schema'\n\nexport const CLIENT_PREFIX = 'PUBLIC_' as const\n\n/**\n * Static, value-free metadata about an environment key. It reaches the manifest\n * and the committed blueprint, so it must never contain a value or a secret.\n */\nexport type EnvVarMeta = {\n /**\n * Whether the value is a secret. Defaults to `true` for server keys and\n * `false` for client keys. A client key can never be sensitive: `PUBLIC_*`\n * values are compiled into the browser bundle.\n */\n sensitive?: boolean\n /** Prose shown to whoever fills this key in. Max 200 characters. */\n description?: string\n}\n\nexport type EnvConfigInput = {\n server?: Record<string, StandardSchemaV1>\n client?: Record<string, StandardSchemaV1>\n /** Explicit value source for client vars (e.g. Vite's import.meta.env). */\n runtimeEnv?: Record<string, unknown>\n /** Value-free metadata per key, keyed by the key's own name. */\n meta?: Record<string, EnvVarMeta>\n}\n\n/** Vars bunderstack itself consumes, always validated. */\nexport type BaseEnv = {\n NODE_ENV?: string\n DATABASE_URL: string\n DATABASE_AUTH_TOKEN?: string\n AUTH_SECRET: string\n RESEND_API_KEY?: string\n BUNDERSTACK_MESSAGING_CONFIG?: string\n BUNDERSTACK_BLUEPRINT_PATH?: string\n BUNDERHOST_ENVIRONMENT_ID?: string\n /** Deployed commit SHA, injected by the platform. Reported by readiness. */\n BUNDERSTACK_REVISION?: string\n}\n\ntype InferVars<T> =\n T extends Record<string, StandardSchemaV1>\n ? { [K in keyof T]: StandardSchemaV1.InferOutput<T[K]> }\n : unknown\n\n// Non-distributive so `ValidatedEnv<undefined>` is BaseEnv, not `never`.\nexport type ValidatedEnv<TEnv extends EnvConfigInput | undefined> = [\n TEnv,\n] extends [EnvConfigInput]\n ? BaseEnv &\n InferVars<NonNullable<TEnv>['server']> &\n InferVars<NonNullable<TEnv>['client']>\n : BaseEnv\n\nexport class BunderstackEnvError extends Error {\n readonly issues: string[]\n\n constructor(issues: string[]) {\n super(`Invalid environment:\\n - ${issues.join('\\n - ')}`)\n this.name = 'BunderstackEnvError'\n this.issues = issues\n }\n}\n\nexport type ValidateEnvOptions = {\n /** Value source; defaults to process.env. Tests pass this explicitly. */\n source?: Record<string, string | undefined>\n /** Dialect-aware DATABASE_URL fallback; bunderstack passes it. */\n defaultDatabaseUrl?: string\n}\n\nconst DEV_AUTH_SECRET = 'dev-secret-change-in-prod'\n\nfunction validateSection(\n section: Record<string, StandardSchemaV1> | undefined,\n kind: 'server' | 'client',\n source: Record<string, unknown>,\n issues: string[],\n out: Record<string, unknown>,\n) {\n for (const [key, schema] of Object.entries(section ?? {})) {\n const isPublic = key.startsWith(CLIENT_PREFIX)\n if (kind === 'server' && isPublic) {\n issues.push(\n `${key}: server vars must not start with ${CLIENT_PREFIX} (move it to env.client)`,\n )\n continue\n }\n if (kind === 'client' && !isPublic) {\n issues.push(\n `${key}: client vars must start with ${CLIENT_PREFIX} (rename it or move it to env.server)`,\n )\n continue\n }\n try {\n out[key] = validateStandardSchema(schema, source[key], 'env')\n } catch (error) {\n if (!(error instanceof StandardSchemaValidationError)) throw error\n for (const issue of error.issues) {\n const path = issue.path.map(String).join('.')\n issues.push(`${key}${path ? `.${path}` : ''}: ${issue.message}`)\n }\n }\n }\n}\n\nexport function validateEnv<TEnv extends EnvConfigInput | undefined>(\n envConfig: TEnv,\n options: ValidateEnvOptions = {},\n): ValidatedEnv<TEnv> {\n const source =\n options.source ?? (process.env as Record<string, string | undefined>)\n const issues: string[] = []\n const isProduction = source.NODE_ENV === 'production'\n\n const base: BaseEnv = {\n NODE_ENV: source.NODE_ENV,\n DATABASE_URL:\n source.DATABASE_URL ?? options.defaultDatabaseUrl ?? 'file:./data.db',\n DATABASE_AUTH_TOKEN: source.DATABASE_AUTH_TOKEN,\n AUTH_SECRET: source.AUTH_SECRET ?? DEV_AUTH_SECRET,\n RESEND_API_KEY: source.RESEND_API_KEY,\n BUNDERSTACK_MESSAGING_CONFIG: source.BUNDERSTACK_MESSAGING_CONFIG,\n BUNDERSTACK_BLUEPRINT_PATH: source.BUNDERSTACK_BLUEPRINT_PATH,\n BUNDERHOST_ENVIRONMENT_ID: source.BUNDERHOST_ENVIRONMENT_ID,\n BUNDERSTACK_REVISION: source.BUNDERSTACK_REVISION,\n }\n if (isProduction && !source.AUTH_SECRET) {\n issues.push('AUTH_SECRET: required in production')\n }\n const userVars: Record<string, unknown> = {}\n validateSection(envConfig?.server, 'server', source, issues, userVars)\n validateSection(envConfig?.client, 'client', source, issues, userVars)\n\n if (issues.length > 0) throw new BunderstackEnvError(issues)\n return { ...base, ...userVars } as ValidatedEnv<TEnv>\n}\n\n/**\n * Browser-side companion (t3-env style): validates ONLY the client section.\n * Server keys exist on the returned object as traps that throw on access, so\n * a leaked import fails loudly instead of silently reading undefined.\n */\nexport function createClientEnv<TEnv extends EnvConfigInput>(\n envConfig: TEnv,\n): InferVars<TEnv['client']> {\n const source =\n envConfig.runtimeEnv ??\n (typeof process !== 'undefined'\n ? (process.env as Record<string, unknown>)\n : {})\n const issues: string[] = []\n const values: Record<string, unknown> = {}\n validateSection(envConfig.client, 'client', source, issues, values)\n if (issues.length > 0) throw new BunderstackEnvError(issues)\n\n const serverKeys = new Set(Object.keys(envConfig.server ?? {}))\n return new Proxy(values, {\n get(target, prop) {\n if (typeof prop === 'string' && serverKeys.has(prop)) {\n throw new Error(\n `${prop} is server-only and not available in client env`,\n )\n }\n return Reflect.get(target, prop)\n },\n }) as InferVars<TEnv['client']>\n}\n"]}
|
package/dist/handler.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import type { RateLimitStore } from './platform.js';
|
|
1
2
|
import { type RateLimitConfig } from './rate-limit.js';
|
|
2
3
|
interface HandlerParts {
|
|
3
4
|
authHandler?: (req: Request) => Promise<Response>;
|
|
4
5
|
apiHandler?: (req: Request) => Promise<Response | null>;
|
|
5
6
|
rateLimit?: boolean | RateLimitConfig;
|
|
7
|
+
rateLimitStore?: RateLimitStore;
|
|
6
8
|
}
|
|
7
9
|
export declare function buildHandler(parts: HandlerParts): (req: Request) => Promise<Response>;
|
|
8
10
|
export {};
|
package/dist/handler.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../src/handler.ts"],"names":[],"mappings":"AACA,OAAO,EAAqB,KAAK,eAAe,EAAE,MAAM,cAAc,CAAA;AAEtE,UAAU,YAAY;IACpB,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;IACjD,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAA;IACvD,SAAS,CAAC,EAAE,OAAO,GAAG,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../src/handler.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAEhD,OAAO,EAAqB,KAAK,eAAe,EAAE,MAAM,cAAc,CAAA;AAEtE,UAAU,YAAY;IACpB,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;IACjD,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAA;IACvD,SAAS,CAAC,EAAE,OAAO,GAAG,eAAe,CAAA;IACrC,cAAc,CAAC,EAAE,cAAc,CAAA;CAChC;AAED,wBAAgB,YAAY,CAC1B,KAAK,EAAE,YAAY,GAClB,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAuBrC"}
|
package/dist/handler.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
// src/handler.ts
|
|
2
1
|
import { createRateLimiter } from './rate-limit.js';
|
|
3
2
|
export function buildHandler(parts) {
|
|
4
|
-
const checkRateLimit = createRateLimiter(parts.rateLimit);
|
|
3
|
+
const checkRateLimit = createRateLimiter(parts.rateLimit, parts.rateLimitStore);
|
|
5
4
|
return async (req) => {
|
|
6
5
|
const limited = await checkRateLimit(req);
|
|
7
6
|
if (limited)
|
package/dist/handler.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handler.js","sourceRoot":"","sources":["../src/handler.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"handler.js","sourceRoot":"","sources":["../src/handler.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,iBAAiB,EAAwB,MAAM,cAAc,CAAA;AAStE,MAAM,UAAU,YAAY,CAC1B,KAAmB;IAEnB,MAAM,cAAc,GAAG,iBAAiB,CACtC,KAAK,CAAC,SAAS,EACf,KAAK,CAAC,cAAc,CACrB,CAAA;IAED,OAAO,KAAK,EAAE,GAAY,EAAqB,EAAE;QAC/C,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,GAAG,CAAC,CAAA;QACzC,IAAI,OAAO;YAAE,OAAO,OAAO,CAAA;QAE3B,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAA;QAC1C,IACE,KAAK,CAAC,WAAW;YACjB,CAAC,QAAQ,KAAK,WAAW,IAAI,QAAQ,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,EAC/D,CAAC;YACD,OAAO,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,CAAA;QAC/B,CAAC;QACD,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;YACrB,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAA;YAC1C,IAAI,MAAM;gBAAE,OAAO,MAAM,CAAA;QAC3B,CAAC;QACD,OAAO,IAAI,QAAQ,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAA;IACnD,CAAC,CAAA;AACH,CAAC","sourcesContent":["// src/handler.ts\nimport type { RateLimitStore } from './platform'\n\nimport { createRateLimiter, type RateLimitConfig } from './rate-limit'\n\ninterface HandlerParts {\n authHandler?: (req: Request) => Promise<Response>\n apiHandler?: (req: Request) => Promise<Response | null>\n rateLimit?: boolean | RateLimitConfig\n rateLimitStore?: RateLimitStore\n}\n\nexport function buildHandler(\n parts: HandlerParts,\n): (req: Request) => Promise<Response> {\n const checkRateLimit = createRateLimiter(\n parts.rateLimit,\n parts.rateLimitStore,\n )\n\n return async (req: Request): Promise<Response> => {\n const limited = await checkRateLimit(req)\n if (limited) return limited\n\n const pathname = new URL(req.url).pathname\n if (\n parts.authHandler &&\n (pathname === '/api/auth' || pathname.startsWith('/api/auth/'))\n ) {\n return parts.authHandler(req)\n }\n if (parts.apiHandler) {\n const apiRes = await parts.apiHandler(req)\n if (apiRes) return apiRes\n }\n return new Response('Not Found', { status: 404 })\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hosted-contract.d.ts","sourceRoot":"","sources":["../src/hosted-contract.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"hosted-contract.d.ts","sourceRoot":"","sources":["../src/hosted-contract.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAA;AAKrD,qBAAa,4BAA6B,SAAQ,KAAK;gBACzC,KAAK,EAAE,SAAS;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE;CAO7D;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,mBAAmB,CAuBzE;AAED,wBAAgB,8BAA8B,CAC5C,QAAQ,EAAE,mBAAmB,EAC7B,MAAM,EAAE,MAAM,GACb,IAAI,CAIN;AAED,wBAAsB,yBAAyB,CAC7C,QAAQ,EAAE,mBAAmB,EAC7B,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC,CAQf"}
|
package/dist/hosted-contract.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
1
2
|
import { parseBlueprintYaml } from './blueprint.js';
|
|
2
3
|
import { diffManifests } from './manifest-diff.js';
|
|
3
4
|
export class HostedBlueprintMismatchError extends Error {
|
|
@@ -37,10 +38,13 @@ export function assertManifestMatchesBlueprint(manifest, source) {
|
|
|
37
38
|
throw new HostedBlueprintMismatchError(differences);
|
|
38
39
|
}
|
|
39
40
|
export async function assertHostedBlueprintFile(manifest, path) {
|
|
40
|
-
|
|
41
|
-
|
|
41
|
+
let source;
|
|
42
|
+
try {
|
|
43
|
+
source = await readFile(path, 'utf8');
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
42
46
|
throw new Error(`[bunderstack] hosted blueprint does not exist: ${path}`);
|
|
43
47
|
}
|
|
44
|
-
assertManifestMatchesBlueprint(manifest,
|
|
48
|
+
assertManifestMatchesBlueprint(manifest, source);
|
|
45
49
|
}
|
|
46
50
|
//# sourceMappingURL=hosted-contract.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hosted-contract.js","sourceRoot":"","sources":["../src/hosted-contract.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"hosted-contract.js","sourceRoot":"","sources":["../src/hosted-contract.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAI3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAE/C,MAAM,OAAO,4BAA6B,SAAQ,KAAK;IACrD,YAAY,KAAgD;QAC1D,KAAK,CACH,6EAA6E;YAC3E,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,OAAO,IAAI,KAAK,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CACnE,CAAA;QACD,IAAI,CAAC,IAAI,GAAG,8BAA8B,CAAA;IAC5C,CAAC;CACF;AAED,MAAM,UAAU,qBAAqB,CAAC,MAAc;IAClD,MAAM,SAAS,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAA;IAC5C,OAAO;QACL,OAAO,EAAE,SAAS,CAAC,WAAW,CAAC,eAAe;QAC9C,QAAQ,EAAE;YACR,OAAO,EAAE,SAAS,CAAC,SAAS,CAAC,QAAQ,CAAC,OAAO;YAC7C,mBAAmB,EAAE,SAAS,CAAC,SAAS,CAAC,QAAQ,CAAC,mBAAmB;YACrE,MAAM,EAAE,SAAS,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM;SAC5C;QACD,OAAO,EAAE,SAAS,CAAC,SAAS,CAAC,OAAO;QACpC,QAAQ,EAAE,SAAS,CAAC,SAAS,CAAC,QAAQ,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE;QAC7D,SAAS,EAAE,SAAS,CAAC,SAAS,CAAC,SAAS;QACxC,WAAW,EAAE,SAAS,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YACjD,GAAG,KAAK;YACR,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,KAAK,KAAK,QAAQ;SACvD,CAAC,CAAC;QACH,GAAG,EAAE,SAAS,CAAC,GAAG,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE;QACxC,UAAU,EAAE;YACV,IAAI,EAAE,SAAS,CAAC,UAAU,CAAC,IAAI;YAC/B,IAAI,EAAE,SAAS,CAAC,UAAU,CAAC,IAAI;YAC/B,WAAW,EAAE,SAAS,CAAC,UAAU,CAAC,WAAW;SAC9C;KACF,CAAA;AACH,CAAC;AAED,MAAM,UAAU,8BAA8B,CAC5C,QAA6B,EAC7B,MAAc;IAEd,MAAM,WAAW,GAAG,aAAa,CAAC,qBAAqB,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,CAAA;IAC1E,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC;QACxB,MAAM,IAAI,4BAA4B,CAAC,WAAW,CAAC,CAAA;AACvD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAC7C,QAA6B,EAC7B,IAAY;IAEZ,IAAI,MAAc,CAAA;IAClB,IAAI,CAAC;QACH,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;IACvC,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,kDAAkD,IAAI,EAAE,CAAC,CAAA;IAC3E,CAAC;IACD,8BAA8B,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;AAClD,CAAC","sourcesContent":["import { readFile } from 'node:fs/promises'\n\nimport type { BunderstackManifest } from './manifest'\n\nimport { parseBlueprintYaml } from './blueprint'\nimport { diffManifests } from './manifest-diff'\n\nexport class HostedBlueprintMismatchError extends Error {\n constructor(paths: readonly { kind: string; path: string }[]) {\n super(\n '[bunderstack] runtime declaration does not match the committed blueprint:\\n' +\n paths.map(({ kind, path }) => ` - ${kind}: ${path}`).join('\\n'),\n )\n this.name = 'HostedBlueprintMismatchError'\n }\n}\n\nexport function manifestFromBlueprint(source: string): BunderstackManifest {\n const blueprint = parseBlueprintYaml(source)\n return {\n version: blueprint.bunderstack.manifestVersion,\n database: {\n dialect: blueprint.resources.database.dialect,\n migrationsDirectory: blueprint.resources.database.migrationsDirectory,\n tables: blueprint.resources.database.tables,\n },\n storage: blueprint.resources.storage,\n realtime: blueprint.resources.realtime ?? { required: false },\n messaging: blueprint.resources.messaging,\n environment: blueprint.environment.map((entry) => ({\n ...entry,\n sensitive: entry.sensitive ?? entry.scope === 'server',\n })),\n api: blueprint.api ?? { operations: [] },\n background: {\n jobs: blueprint.background.jobs,\n cron: blueprint.background.cron,\n maintenance: blueprint.background.maintenance,\n },\n }\n}\n\nexport function assertManifestMatchesBlueprint(\n manifest: BunderstackManifest,\n source: string,\n): void {\n const differences = diffManifests(manifestFromBlueprint(source), manifest)\n if (differences.length > 0)\n throw new HostedBlueprintMismatchError(differences)\n}\n\nexport async function assertHostedBlueprintFile(\n manifest: BunderstackManifest,\n path: string,\n): Promise<void> {\n let source: string\n try {\n source = await readFile(path, 'utf8')\n } catch {\n throw new Error(`[bunderstack] hosted blueprint does not exist: ${path}`)\n }\n assertManifestMatchesBlueprint(manifest, source)\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
export * from './backend.js';
|
|
2
2
|
export { createMessaging, resend, customEmail, telegram } from './messaging/index.js';
|
|
3
3
|
export type { MessagingConfig, MessagingDescriptor, MessagingFacade, MessagingFacades, TelegramMessage, } from './messaging/index.js';
|
|
4
|
-
export type {
|
|
4
|
+
export type { AuthInstance, BucketNamesOf, BunderstackApp, StorageFacade, } from './runtime.js';
|
|
5
|
+
export type { JobsPlatform, Platform, RateLimitHit, RateLimitStore, StorageAdapterFactory, } from './platform.js';
|
|
6
|
+
export { createMemoryRateLimitStore, resolvePlatform } from './platform.js';
|
|
5
7
|
export { listSpec } from './api/list-spec.js';
|
|
6
8
|
export type { ListSpecOptions } from './api/list-spec.js';
|
|
7
9
|
export type { BunderstackDb, BunderstackTx } from './db.js';
|
|
@@ -18,7 +20,7 @@ export { buildReadinessReport, readinessReportSchema } from './readiness.js';
|
|
|
18
20
|
export type { ReadinessCheck, ReadinessCheckName, ReadinessCode, ReadinessReport, ReadinessStatus, } from './readiness.js';
|
|
19
21
|
export type { EmailMessage, EmailAdapter } from './email.js';
|
|
20
22
|
export { createJobsBuilder } from './jobs/index.js';
|
|
21
|
-
export type { BunderstackJobContext, BunderstackJobsBuilder, BackgroundDefinition, BackgroundDefs, CronDefinition, CronInvocation, DedupeUntil, EnqueueOptions, EnqueueTransaction, JobContext, JobDefinition, JobsDefs, JobsFacade, JobsRuntimeFacade, QueueJobDefinition, QueueJobKeys, TypedEnqueueOptions,
|
|
23
|
+
export type { BunderstackJobContext, BunderstackJobsBuilder, BackgroundDefinition, BackgroundDefs, CronDefinition, CronInvocation, DedupeUntil, EnqueueOptions, EnqueueTransaction, JobContext, JobDefinition, JobsDefs, JobsFacade, JobsRuntimeFacade, QueueJobDefinition, QueueJobKeys, TypedEnqueueOptions, } from './jobs/index.js';
|
|
22
24
|
export { defineSessionUser, defineAccess, validateAndResolveAccess, checkAccess, AUTH_TABLE_NAMES, } from './access.js';
|
|
23
25
|
export type { TableAccessInput, OperationRule, AccessContext, AccessUser, AccessUserBase, SessionUserConfig, SessionUserExtraOf, SessionUserSource, } from './access.js';
|
|
24
26
|
export { typeid, generate as generateTypeId, parse as parseTypeId, asTypeId, } from './typeid.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAA;AACzB,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAC5E,YAAY,EACV,eAAe,EACf,mBAAmB,EACnB,eAAe,EACf,gBAAgB,EAChB,eAAe,GAChB,MAAM,aAAa,CAAA;AACpB,YAAY,EACV,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export * from './backend.js';
|
|
2
2
|
export { createMessaging, resend, customEmail, telegram } from './messaging/index.js';
|
|
3
|
+
export { createMemoryRateLimitStore, resolvePlatform } from './platform.js';
|
|
3
4
|
export { listSpec } from './api/list-spec.js';
|
|
4
5
|
export { MAX_LIST_LIMIT } from './list-query.js';
|
|
5
6
|
export { BunderstackError } from './errors.js';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAA;AACzB,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAA;AACzB,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAqB5E,OAAO,EAAE,0BAA0B,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AACxE,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAG1C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAA;AAE3C,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AASvE,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,OAAO,CAAA;AAEzE,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAOzD,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AASzE,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AAoBhD,OAAO,EACL,iBAAiB,EACjB,YAAY,EACZ,wBAAwB,EACxB,WAAW,EACX,gBAAgB,GACjB,MAAM,UAAU,CAAA;AAWjB,OAAO,EACL,MAAM,EACN,QAAQ,IAAI,cAAc,EAC1B,KAAK,IAAI,WAAW,EACpB,QAAQ,GACT,MAAM,UAAU,CAAA;AAejB,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAA;AAMxD,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAU3D,OAAO,EACL,gBAAgB,EAChB,qBAAqB,EACrB,gBAAgB,EAChB,2BAA2B,GAC5B,MAAM,gBAAgB,CAAA;AACvB,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA","sourcesContent":["export * from './backend'\nexport { createMessaging, resend, customEmail, telegram } from './messaging'\nexport type {\n MessagingConfig,\n MessagingDescriptor,\n MessagingFacade,\n MessagingFacades,\n TelegramMessage,\n} from './messaging'\nexport type {\n AuthInstance,\n BucketNamesOf,\n BunderstackApp,\n StorageFacade,\n} from './runtime'\nexport type {\n JobsPlatform,\n Platform,\n RateLimitHit,\n RateLimitStore,\n StorageAdapterFactory,\n} from './platform'\nexport { createMemoryRateLimitStore, resolvePlatform } from './platform'\nexport { listSpec } from './api/list-spec'\nexport type { ListSpecOptions } from './api/list-spec'\nexport type { BunderstackDb, BunderstackTx } from './db'\nexport { MAX_LIST_LIMIT } from './list-query'\nexport { BunderstackError } from './errors'\nexport type { BunderstackErrorCode } from './errors'\nexport { resolveConfig, resolveAuthConfig, defineAuth } from './config'\nexport type {\n AuthConfigContext,\n AuthConfigFactory,\n AuthConfigInput,\n BetterAuthConfig,\n BunderstackConfig,\n ResolvedConfig,\n} from './config'\nexport { validateEnv, createClientEnv, BunderstackEnvError } from './env'\nexport type { EnvConfigInput, BaseEnv, ValidatedEnv } from './env'\nexport { buildManifest, parseManifest } from './manifest'\nexport type {\n ApiOperation,\n ApiOperationEffect,\n BunderstackManifest,\n ManifestEnvVar,\n} from './manifest'\nexport { buildReadinessReport, readinessReportSchema } from './readiness'\nexport type {\n ReadinessCheck,\n ReadinessCheckName,\n ReadinessCode,\n ReadinessReport,\n ReadinessStatus,\n} from './readiness'\nexport type { EmailMessage, EmailAdapter } from './email'\nexport { createJobsBuilder } from './jobs/index'\nexport type {\n BunderstackJobContext,\n BunderstackJobsBuilder,\n BackgroundDefinition,\n BackgroundDefs,\n CronDefinition,\n CronInvocation,\n DedupeUntil,\n EnqueueOptions,\n EnqueueTransaction,\n JobContext,\n JobDefinition,\n JobsDefs,\n JobsFacade,\n JobsRuntimeFacade,\n QueueJobDefinition,\n QueueJobKeys,\n TypedEnqueueOptions,\n} from './jobs/index'\nexport {\n defineSessionUser,\n defineAccess,\n validateAndResolveAccess,\n checkAccess,\n AUTH_TABLE_NAMES,\n} from './access'\nexport type {\n TableAccessInput,\n OperationRule,\n AccessContext,\n AccessUser,\n AccessUserBase,\n SessionUserConfig,\n SessionUserExtraOf,\n SessionUserSource,\n} from './access'\nexport {\n typeid,\n generate as generateTypeId,\n parse as parseTypeId,\n asTypeId,\n} from './typeid'\nexport type { TypeId } from './typeid'\nexport type {\n DatabaseAdapter,\n DatabaseConnection,\n DatabaseConnectionResult,\n} from './database/adapter'\nexport type { StorageAdapter } from './storage/index'\nexport type {\n StorageConfigInput,\n BucketConfigInput,\n ResolvedBucket,\n} from './storage/buckets'\nexport type { TransformSpec } from './storage/thumbnails'\nexport type { RealtimeAction } from './realtime/publisher'\nexport { createRealtimeFacade } from './realtime/facade'\nexport type {\n RealtimeFacade,\n RealtimeTransport,\n SchemaTable,\n} from './realtime/facade'\nexport { createApiBuilder, defineApi } from './api/builder'\nexport type { BunderstackApiBuilder, ApiFactory } from './api/builder'\nexport type { ApiContext } from './api/context'\nexport type {\n CrudApiRouterFor,\n ExposedApiTables,\n MergeApiRouterTypes,\n UnifiedApiRouter,\n} from './api/types'\nexport type { TableCrudProcedures } from './api/crud-router'\nexport {\n buildApiRegistry,\n mergeApiRoutersStrict,\n normalizeApiPath,\n normalizeForeignOpenAPISpec,\n} from './api/registry'\nexport { mergeOpenAPISpecs } from './api/openapi'\n"]}
|
package/dist/jobs/define.d.ts
CHANGED
|
@@ -74,6 +74,11 @@ export type JobsRuntimeFacade = {
|
|
|
74
74
|
}>;
|
|
75
75
|
/** Run one poll cycle deterministically (tests). `now` defaults to Date.now(). */
|
|
76
76
|
tick(now?: number): Promise<TickResult>;
|
|
77
|
+
/**
|
|
78
|
+
* When the next background work is due, for a host scheduler. Never earlier
|
|
79
|
+
* than `now`; null when nothing is due before `until` (default: 24 h later).
|
|
80
|
+
*/
|
|
81
|
+
nextDueAt(now?: number, until?: number): Promise<number | null>;
|
|
77
82
|
};
|
|
78
83
|
import type { RealtimeFacade } from '../realtime/facade.js';
|
|
79
84
|
export type JobContext<TSchema extends Record<string, unknown> = Record<string, unknown>, TEnvResult = Record<string, unknown>, TMessaging extends MessagingConfig | undefined = MessagingConfig> = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"define.d.ts","sourceRoot":"","sources":["../../src/jobs/define.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAE7D,OAAO,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,OAAO,CAAA;AACjD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AACvC,OAAO,KAAK,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA;AACxE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAG/C,OAAO,EAAe,KAAK,OAAO,EAAE,MAAM,SAAS,CAAA;AAEnD,eAAO,MAAM,eAAe,IAAI,CAAA;AAChC,eAAO,MAAM,yBAAyB,QAAS,CAAA;AAC/C,iDAAiD;AACjD,eAAO,MAAM,kBAAkB,QAA4B,CAAA;AAE3D,MAAM,MAAM,gBAAgB,GAAG;IAC7B,4EAA4E;IAC5E,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,qDAAqD;IACrD,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,qCAAqC;IACrC,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,gBAAgB,EAAE,GAAG,EAAE,CAAC,GAAG,MAAM,CAE3E;AAED;;;;GAIG;AACH,MAAM,MAAM,kBAAkB,GAAG,KAAK,CAAA;AAEtC,MAAM,MAAM,cAAc,GAAG;IAC3B;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,6DAA6D;IAC7D,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,kEAAkE;IAClE,KAAK,CAAC,EAAE,IAAI,GAAG,MAAM,CAAA;IACrB;;;;OAIG;IACH,EAAE,CAAC,EAAE,kBAAkB,CAAA;CACxB,CAAA;AAED,gFAAgF;AAChF,MAAM,MAAM,mBAAmB,CAAC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,IAAI,CAC7E,cAAc,EACd,IAAI,CACL,GAAG;IACF;;;OAGG;IACH,EAAE,CAAC,EAAE,aAAa,CAAC,OAAO,CAAC,CAAA;CAC5B,CAAA;AAED;;;;;GAKG;AACH,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,QAAQ,CAAA;AAE5C,MAAM,MAAM,UAAU,GAAG;IACvB,oDAAoD;IACpD,OAAO,EAAE,MAAM,CAAA;IACf,4CAA4C;IAC5C,GAAG,EAAE,MAAM,CAAA;IACX,gEAAgE;IAChE,MAAM,EAAE,MAAM,CAAA;CACf,CAAA;AAED;;;GAGG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,OAAO,CACL,IAAI,EAAE,MAAM,EACZ,KAAK,CAAC,EAAE,OAAO,EACf,IAAI,CAAC,EAAE,cAAc,GACpB,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAC1B,kFAAkF;IAClF,IAAI,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"define.d.ts","sourceRoot":"","sources":["../../src/jobs/define.ts"],"names":[],"mappings":"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"}
|
package/dist/jobs/define.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"define.js","sourceRoot":"","sources":["../../src/jobs/define.ts"],"names":[],"mappings":"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","sourcesContent":["// src/jobs/define.ts — job definition types and the typed builder.\n// `createJobsBuilder` exists purely to carry\n// TSchema/TEnvResult typing into inline callbacks and extracted files.\nimport type { StandardSchemaV1 } from '@standard-schema/spec'\n\nimport type { BunderstackTx, DbFor } from '../db'\nimport type { AnyDb } from '../dialect'\nimport type { MessagingConfig, MessagingFacadesFor } from '../messaging'\nimport type { StorageFacade } from '../runtime'\n\nimport { parseCron } from './cron'\nimport { CRON_PREFIX, type CatchUp } from './slots'\n\nexport const DEFAULT_RETRIES = 3\nexport const DEFAULT_LEASE_DURATION_MS = 60_000\n/** @deprecated Use DEFAULT_LEASE_DURATION_MS. */\nexport const DEFAULT_TIMEOUT_MS = DEFAULT_LEASE_DURATION_MS\n\nexport type BackgroundTiming = {\n /** Lease duration in ms; an expired lease sends the job back to pending. */\n leaseDuration?: number\n /** Optional cooperative execution deadline in ms. */\n maxRuntime?: number\n /** @deprecated Use leaseDuration. */\n timeout?: number\n}\n\nexport function leaseDurationFor<T extends BackgroundTiming>(def: T): number {\n return def.leaseDuration ?? def.timeout ?? DEFAULT_LEASE_DURATION_MS\n}\n\n/**\n * Structural view of a Drizzle database or transaction handle that `enqueue`\n * can insert through. The loose runtime facade accepts any handle of the app's\n * dialect; `app.jobs` narrows it to the app's `BunderstackTx`.\n */\nexport type EnqueueTransaction = AnyDb\n\nexport type EnqueueOptions = {\n /**\n * Collapse duplicate enqueues while the queue row holds its key: until a\n * terminal state by default, or until it is claimed with\n * `dedupeUntil: 'start'`.\n */\n dedupeKey?: string\n /** Milliseconds from now until the job becomes claimable. */\n delay?: number\n /** Absolute time the job becomes claimable; wins over `delay`. */\n runAt?: Date | number\n /**\n * Insert the job row through this transaction. The job becomes visible to\n * workers only when the transaction commits; a rollback removes it. Must be\n * a transaction on the app's own database.\n */\n tx?: EnqueueTransaction\n}\n\n/** `EnqueueOptions` with `tx` narrowed to the app schema's transaction type. */\nexport type TypedEnqueueOptions<TSchema extends Record<string, unknown>> = Omit<\n EnqueueOptions,\n 'tx'\n> & {\n /**\n * Insert the job row through this transaction. The job becomes visible to\n * workers only when the transaction commits; a rollback removes it.\n */\n tx?: BunderstackTx<TSchema>\n}\n\n/**\n * How long a queue job's `dedupeKey` collapses new enqueues.\n * - `'finish'` (default): until the job reaches a terminal state.\n * - `'start'`: until a worker claims the job; later enqueues create a new row\n * that runs after it and reads the newer state.\n */\nexport type DedupeUntil = 'start' | 'finish'\n\nexport type TickResult = {\n /** Rows moved from pending to running this tick. */\n claimed: number\n /** Handlers that completed successfully. */\n ran: number\n /** Handlers that threw, whether or not they will be retried. */\n failed: number\n}\n\n/**\n * The untyped runtime facade. Job handlers and API context expose this shape;\n * `app.jobs` narrows `enqueue` to the declared job names/payloads.\n */\nexport type JobsRuntimeFacade = {\n enqueue(\n name: string,\n input?: unknown,\n opts?: EnqueueOptions,\n ): Promise<{ id: string }>\n /** Run one poll cycle deterministically (tests). `now` defaults to Date.now(). */\n tick(now?: number): Promise<TickResult>\n}\n\nimport type { RealtimeFacade } from '../realtime/facade'\n\nexport type JobContext<\n TSchema extends Record<string, unknown> = Record<string, unknown>,\n TEnvResult = Record<string, unknown>,\n TMessaging extends MessagingConfig | undefined = MessagingConfig,\n> = {\n db: DbFor<TSchema>\n env: TEnvResult\n messaging: MessagingFacadesFor<TMessaging>\n storage: StorageFacade\n jobs: JobsRuntimeFacade\n realtime: RealtimeFacade<TSchema>\n /** Aborted when execution reaches its deadline or the job loses its lease. */\n signal: AbortSignal\n}\n\nexport type BunderstackJobContext<\n TSchema extends Record<string, unknown> = Record<string, unknown>,\n TEnvResult = Record<string, unknown>,\n TMessaging extends MessagingConfig | undefined = MessagingConfig,\n> = JobContext<TSchema, TEnvResult, TMessaging>\n\nexport type QueueJobDefinition<\n TInput,\n TSchema extends Record<string, unknown> = Record<string, unknown>,\n TEnvResult = Record<string, unknown>,\n TMessaging extends MessagingConfig | undefined = MessagingConfig,\n> = BackgroundTiming & {\n kind: 'job'\n /** Standard Schema payload; parsed at enqueue AND before the handler runs. */\n input?: StandardSchemaV1<unknown, TInput>\n /** Attempts after the first failure. Default 3 (so 4 total attempts). */\n retries?: number\n /** Delay before retry N (1-based). Default exponential: 1s, 2s, 4s, … */\n backoff?: ((attempt: number) => number) | { baseMs?: number; factor?: number }\n /** Max simultaneous `running` rows of this type, enforced per worker. */\n concurrency?: number\n /**\n * When a `dedupeKey` stops collapsing new enqueues. Default `'finish'`:\n * held until a terminal state. `'start'`: released when a worker claims the\n * job, so an enqueue during the run schedules one more run.\n */\n dedupeUntil?: DedupeUntil\n handler: (\n input: TInput,\n ctx: JobContext<TSchema, TEnvResult, TMessaging>,\n ) => Promise<void> | void\n /** Fires once, after the final attempt fails. Errors here are logged, never retried. */\n onFailed?: (\n input: TInput,\n error: Error,\n ctx: JobContext<TSchema, TEnvResult, TMessaging>,\n ) => Promise<void> | void\n}\n\nexport type CronInvocation = { scheduledFor: Date }\n\nexport type CronDefinition<\n TSchema extends Record<string, unknown> = Record<string, unknown>,\n TEnvResult = Record<string, unknown>,\n TSchedule extends string = string,\n TMessaging extends MessagingConfig | undefined = MessagingConfig,\n> = BackgroundTiming & {\n kind: 'cron'\n schedule: TSchedule\n /** Attempts after the first failure. Default 3 (so 4 total attempts). */\n retries?: number\n /** Delay before retry N (1-based). Default exponential: 1s, 2s, 4s, … */\n backoff?: ((attempt: number) => number) | { baseMs?: number; factor?: number }\n /** How missed slots are handled on wake. Default 'latest'. */\n catchUp?: CatchUp\n /** How far back catch-up looks, in ms. Default 1 hour. */\n catchUpWindow?: number\n handler: (\n invocation: CronInvocation,\n ctx: JobContext<TSchema, TEnvResult, TMessaging>,\n ) => Promise<void> | void\n /** Fires once, after the final attempt fails. Errors here are logged, never retried. */\n onFailed?: (\n invocation: CronInvocation,\n error: Error,\n ctx: JobContext<TSchema, TEnvResult, TMessaging>,\n ) => Promise<void> | void\n}\n\nexport type BackgroundDefinition =\n | QueueJobDefinition<any, any, any, any>\n | CronDefinition<any, any, any, any>\nexport type BackgroundDefs = Record<string, BackgroundDefinition>\n\n/** @deprecated Use QueueJobDefinition. */\nexport type JobDefinition<\n TInput,\n TSchema extends Record<string, unknown> = Record<string, unknown>,\n TEnvResult = Record<string, unknown>,\n TMessaging extends MessagingConfig | undefined = MessagingConfig,\n> = QueueJobDefinition<TInput, TSchema, TEnvResult, TMessaging>\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type AnyJobDefinition = QueueJobDefinition<any, any, any, any>\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type AnyBackgroundDefinition =\n | QueueJobDefinition<any, any, any, any>\n | CronDefinition<any, any, any, any>\nexport type JobsDefs = BackgroundDefs\n\nexport type QueueJobKeys<TDefs extends BackgroundDefs> = {\n [K in keyof TDefs & string]: TDefs[K] extends QueueJobDefinition<\n any,\n any,\n any,\n any\n >\n ? K\n : never\n}[keyof TDefs & string]\n\n/** Throws when a definition is unusable. Safe to call more than once. */\nexport function validateBackgroundDefs(defs: BackgroundDefs): void {\n for (const [name, def] of Object.entries(defs)) {\n if (typeof def.handler !== 'function') {\n throw new Error(`[bunderstack] background task \"${name}\" has no handler`)\n }\n if (def.kind === 'job' && name.startsWith(CRON_PREFIX)) {\n throw new Error(\n `[bunderstack] job \"${name}\": the \"${CRON_PREFIX}\" prefix is reserved for cron tasks`,\n )\n }\n if (\n def.retries !== undefined &&\n (def.retries < 0 || !Number.isInteger(def.retries))\n ) {\n throw new Error(\n `[bunderstack] background task \"${name}\": retries must be a non-negative integer`,\n )\n }\n if (def.timeout !== undefined && def.leaseDuration !== undefined) {\n throw new Error(\n `[bunderstack] background task \"${name}\": timeout and leaseDuration cannot both be declared`,\n )\n }\n for (const field of ['timeout', 'leaseDuration', 'maxRuntime'] as const) {\n const value = def[field]\n if (\n value !== undefined &&\n (!Number.isFinite(value) || !Number.isInteger(value) || value <= 0)\n ) {\n throw new Error(\n `[bunderstack] background task \"${name}\": ${field} must be a positive finite integer`,\n )\n }\n }\n if (def.kind === 'cron') {\n parseCron(def.schedule)\n assertCronHasNoDedupeUntil(def, `cron \"${name}\"`)\n if ((def as { concurrency?: number }).concurrency !== undefined) {\n throw new Error(\n `[bunderstack] cron \"${name}\": concurrency is not supported for cron tasks — slots are already unique`,\n )\n }\n if (def.catchUpWindow !== undefined && def.catchUpWindow <= 0) {\n throw new Error(\n `[bunderstack] cron \"${name}\": catchUpWindow must be positive`,\n )\n }\n continue\n }\n if (\n def.concurrency !== undefined &&\n (def.concurrency < 1 || !Number.isInteger(def.concurrency))\n ) {\n throw new Error(\n `[bunderstack] job \"${name}\": concurrency must be a positive integer`,\n )\n }\n if (\n def.dedupeUntil !== undefined &&\n def.dedupeUntil !== 'start' &&\n def.dedupeUntil !== 'finish'\n ) {\n throw new Error(\n `[bunderstack] job \"${name}\": dedupeUntil must be 'start' or 'finish'`,\n )\n }\n }\n}\n\n/** Cron slot ownership depends on the retained dedupe key. */\nfunction assertCronHasNoDedupeUntil(def: object, label: string): void {\n if ((def as { dedupeUntil?: unknown }).dedupeUntil !== undefined) {\n throw new Error(\n `[bunderstack] ${label}: dedupeUntil is not supported for cron tasks — cron tasks retain their slot key`,\n )\n }\n}\n\n/** @deprecated Use validateBackgroundDefs. */\nexport const validateJobsDefs = validateBackgroundDefs\n\n/**\n * Delay in ms before retry `attempt` (1-based = the attempt that just failed).\n * Jittered by ±20% so a shared outage does not retry every job in lockstep.\n * A caller-supplied backoff function is returned verbatim — the caller owns it.\n */\nexport function backoffMs(\n def: AnyBackgroundDefinition,\n attempt: number,\n): number {\n const b = def.backoff\n if (typeof b === 'function') return b(attempt)\n const baseMs = b?.baseMs ?? 1000\n const factor = b?.factor ?? 2\n const flat = baseMs * factor ** (attempt - 1)\n return Math.round(flat * (0.8 + Math.random() * 0.4))\n}\n\n/**\n * Build the `j` instance bunderstack hands to the config's `jobs` builder\n * callback (and exports for multi-file job setups).\n */\nexport function createJobsBuilder<\n TSchema extends Record<string, unknown>,\n TEnvResult = Record<string, unknown>,\n TMessaging extends MessagingConfig | undefined = MessagingConfig,\n>() {\n return {\n /** Identity with inference: pins TInput from the schema output. */\n job<TInput = undefined>(\n def: Omit<\n QueueJobDefinition<TInput, TSchema, TEnvResult, TMessaging>,\n 'kind'\n >,\n ): QueueJobDefinition<TInput, TSchema, TEnvResult, TMessaging> {\n return { kind: 'job', ...def }\n },\n cron<const TSchedule extends string>(\n def: Omit<\n CronDefinition<TSchema, TEnvResult, TSchedule, TMessaging>,\n 'kind'\n >,\n ): CronDefinition<TSchema, TEnvResult, TSchedule, TMessaging> {\n parseCron(def.schedule)\n assertCronHasNoDedupeUntil(def, 'cron')\n return { kind: 'cron', ...def }\n },\n /** Identity with validation: returns the defs map, typed. */\n define<TDefs extends BackgroundDefs>(defs: TDefs): TDefs {\n validateBackgroundDefs(defs)\n return defs\n },\n }\n}\n\n/** Type of the `j` instance — for builder callbacks declared in separate files. */\nexport type BunderstackJobsBuilder<\n TSchema extends Record<string, unknown>,\n TEnvResult = Record<string, unknown>,\n TMessaging extends MessagingConfig | undefined = MessagingConfig,\n> = ReturnType<typeof createJobsBuilder<TSchema, TEnvResult, TMessaging>>\n\n// Infers TInput from the JobDefinition's own type argument rather than\n// pattern-matching the (optional, so union-with-undefined) `input` property —\n// A required-property pattern fails structurally because `input` is optional,\n// so infer from the definition's own type argument instead.\ntype JobInputOf<TDef> =\n TDef extends QueueJobDefinition<infer TInput, any, any, any>\n ? TInput\n : undefined\n\n/**\n * `app.jobs`: `enqueue` narrowed to declared names + payloads. `Omit`s the\n * runtime facade's loose `enqueue` first — intersecting two same-named\n * methods instead would make TS treat them as overloaded, so the loose\n * `(name: string, ...)` signature would still accept any name.\n */\nexport type JobsFacade<\n TDefs extends JobsDefs,\n TSchema extends Record<string, unknown> | undefined = undefined,\n> = Omit<JobsRuntimeFacade, 'enqueue'> & {\n enqueue<K extends QueueJobKeys<TDefs>>(\n name: K,\n ...rest: JobInputOf<TDefs[K]> extends undefined\n ? [input?: undefined, opts?: JobsFacadeEnqueueOptions<TSchema>]\n : [input: JobInputOf<TDefs[K]>, opts?: JobsFacadeEnqueueOptions<TSchema>]\n ): Promise<{ id: string }>\n}\n\ntype JobsFacadeEnqueueOptions<\n TSchema extends Record<string, unknown> | undefined,\n> = [TSchema] extends [Record<string, unknown>]\n ? TypedEnqueueOptions<TSchema>\n : EnqueueOptions\n"]}
|
|
1
|
+
{"version":3,"file":"define.js","sourceRoot":"","sources":["../../src/jobs/define.ts"],"names":[],"mappings":"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","sourcesContent":["// src/jobs/define.ts — job definition types and the typed builder.\n// `createJobsBuilder` exists purely to carry\n// TSchema/TEnvResult typing into inline callbacks and extracted files.\nimport type { StandardSchemaV1 } from '@standard-schema/spec'\n\nimport type { BunderstackTx, DbFor } from '../db'\nimport type { AnyDb } from '../dialect'\nimport type { MessagingConfig, MessagingFacadesFor } from '../messaging'\nimport type { StorageFacade } from '../runtime'\n\nimport { parseCron } from './cron'\nimport { CRON_PREFIX, type CatchUp } from './slots'\n\nexport const DEFAULT_RETRIES = 3\nexport const DEFAULT_LEASE_DURATION_MS = 60_000\n/** @deprecated Use DEFAULT_LEASE_DURATION_MS. */\nexport const DEFAULT_TIMEOUT_MS = DEFAULT_LEASE_DURATION_MS\n\nexport type BackgroundTiming = {\n /** Lease duration in ms; an expired lease sends the job back to pending. */\n leaseDuration?: number\n /** Optional cooperative execution deadline in ms. */\n maxRuntime?: number\n /** @deprecated Use leaseDuration. */\n timeout?: number\n}\n\nexport function leaseDurationFor<T extends BackgroundTiming>(def: T): number {\n return def.leaseDuration ?? def.timeout ?? DEFAULT_LEASE_DURATION_MS\n}\n\n/**\n * Structural view of a Drizzle database or transaction handle that `enqueue`\n * can insert through. The loose runtime facade accepts any handle of the app's\n * dialect; `app.jobs` narrows it to the app's `BunderstackTx`.\n */\nexport type EnqueueTransaction = AnyDb\n\nexport type EnqueueOptions = {\n /**\n * Collapse duplicate enqueues while the queue row holds its key: until a\n * terminal state by default, or until it is claimed with\n * `dedupeUntil: 'start'`.\n */\n dedupeKey?: string\n /** Milliseconds from now until the job becomes claimable. */\n delay?: number\n /** Absolute time the job becomes claimable; wins over `delay`. */\n runAt?: Date | number\n /**\n * Insert the job row through this transaction. The job becomes visible to\n * workers only when the transaction commits; a rollback removes it. Must be\n * a transaction on the app's own database.\n */\n tx?: EnqueueTransaction\n}\n\n/** `EnqueueOptions` with `tx` narrowed to the app schema's transaction type. */\nexport type TypedEnqueueOptions<TSchema extends Record<string, unknown>> = Omit<\n EnqueueOptions,\n 'tx'\n> & {\n /**\n * Insert the job row through this transaction. The job becomes visible to\n * workers only when the transaction commits; a rollback removes it.\n */\n tx?: BunderstackTx<TSchema>\n}\n\n/**\n * How long a queue job's `dedupeKey` collapses new enqueues.\n * - `'finish'` (default): until the job reaches a terminal state.\n * - `'start'`: until a worker claims the job; later enqueues create a new row\n * that runs after it and reads the newer state.\n */\nexport type DedupeUntil = 'start' | 'finish'\n\nexport type TickResult = {\n /** Rows moved from pending to running this tick. */\n claimed: number\n /** Handlers that completed successfully. */\n ran: number\n /** Handlers that threw, whether or not they will be retried. */\n failed: number\n}\n\n/**\n * The untyped runtime facade. Job handlers and API context expose this shape;\n * `app.jobs` narrows `enqueue` to the declared job names/payloads.\n */\nexport type JobsRuntimeFacade = {\n enqueue(\n name: string,\n input?: unknown,\n opts?: EnqueueOptions,\n ): Promise<{ id: string }>\n /** Run one poll cycle deterministically (tests). `now` defaults to Date.now(). */\n tick(now?: number): Promise<TickResult>\n /**\n * When the next background work is due, for a host scheduler. Never earlier\n * than `now`; null when nothing is due before `until` (default: 24 h later).\n */\n nextDueAt(now?: number, until?: number): Promise<number | null>\n}\n\nimport type { RealtimeFacade } from '../realtime/facade'\n\nexport type JobContext<\n TSchema extends Record<string, unknown> = Record<string, unknown>,\n TEnvResult = Record<string, unknown>,\n TMessaging extends MessagingConfig | undefined = MessagingConfig,\n> = {\n db: DbFor<TSchema>\n env: TEnvResult\n messaging: MessagingFacadesFor<TMessaging>\n storage: StorageFacade\n jobs: JobsRuntimeFacade\n realtime: RealtimeFacade<TSchema>\n /** Aborted when execution reaches its deadline or the job loses its lease. */\n signal: AbortSignal\n}\n\nexport type BunderstackJobContext<\n TSchema extends Record<string, unknown> = Record<string, unknown>,\n TEnvResult = Record<string, unknown>,\n TMessaging extends MessagingConfig | undefined = MessagingConfig,\n> = JobContext<TSchema, TEnvResult, TMessaging>\n\nexport type QueueJobDefinition<\n TInput,\n TSchema extends Record<string, unknown> = Record<string, unknown>,\n TEnvResult = Record<string, unknown>,\n TMessaging extends MessagingConfig | undefined = MessagingConfig,\n> = BackgroundTiming & {\n kind: 'job'\n /** Standard Schema payload; parsed at enqueue AND before the handler runs. */\n input?: StandardSchemaV1<unknown, TInput>\n /** Attempts after the first failure. Default 3 (so 4 total attempts). */\n retries?: number\n /** Delay before retry N (1-based). Default exponential: 1s, 2s, 4s, … */\n backoff?: ((attempt: number) => number) | { baseMs?: number; factor?: number }\n /** Max simultaneous `running` rows of this type, enforced per worker. */\n concurrency?: number\n /**\n * When a `dedupeKey` stops collapsing new enqueues. Default `'finish'`:\n * held until a terminal state. `'start'`: released when a worker claims the\n * job, so an enqueue during the run schedules one more run.\n */\n dedupeUntil?: DedupeUntil\n handler: (\n input: TInput,\n ctx: JobContext<TSchema, TEnvResult, TMessaging>,\n ) => Promise<void> | void\n /** Fires once, after the final attempt fails. Errors here are logged, never retried. */\n onFailed?: (\n input: TInput,\n error: Error,\n ctx: JobContext<TSchema, TEnvResult, TMessaging>,\n ) => Promise<void> | void\n}\n\nexport type CronInvocation = { scheduledFor: Date }\n\nexport type CronDefinition<\n TSchema extends Record<string, unknown> = Record<string, unknown>,\n TEnvResult = Record<string, unknown>,\n TSchedule extends string = string,\n TMessaging extends MessagingConfig | undefined = MessagingConfig,\n> = BackgroundTiming & {\n kind: 'cron'\n schedule: TSchedule\n /** Attempts after the first failure. Default 3 (so 4 total attempts). */\n retries?: number\n /** Delay before retry N (1-based). Default exponential: 1s, 2s, 4s, … */\n backoff?: ((attempt: number) => number) | { baseMs?: number; factor?: number }\n /** How missed slots are handled on wake. Default 'latest'. */\n catchUp?: CatchUp\n /** How far back catch-up looks, in ms. Default 1 hour. */\n catchUpWindow?: number\n handler: (\n invocation: CronInvocation,\n ctx: JobContext<TSchema, TEnvResult, TMessaging>,\n ) => Promise<void> | void\n /** Fires once, after the final attempt fails. Errors here are logged, never retried. */\n onFailed?: (\n invocation: CronInvocation,\n error: Error,\n ctx: JobContext<TSchema, TEnvResult, TMessaging>,\n ) => Promise<void> | void\n}\n\nexport type BackgroundDefinition =\n | QueueJobDefinition<any, any, any, any>\n | CronDefinition<any, any, any, any>\nexport type BackgroundDefs = Record<string, BackgroundDefinition>\n\n/** @deprecated Use QueueJobDefinition. */\nexport type JobDefinition<\n TInput,\n TSchema extends Record<string, unknown> = Record<string, unknown>,\n TEnvResult = Record<string, unknown>,\n TMessaging extends MessagingConfig | undefined = MessagingConfig,\n> = QueueJobDefinition<TInput, TSchema, TEnvResult, TMessaging>\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type AnyJobDefinition = QueueJobDefinition<any, any, any, any>\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type AnyBackgroundDefinition =\n | QueueJobDefinition<any, any, any, any>\n | CronDefinition<any, any, any, any>\nexport type JobsDefs = BackgroundDefs\n\nexport type QueueJobKeys<TDefs extends BackgroundDefs> = {\n [K in keyof TDefs & string]: TDefs[K] extends QueueJobDefinition<\n any,\n any,\n any,\n any\n >\n ? K\n : never\n}[keyof TDefs & string]\n\n/** Throws when a definition is unusable. Safe to call more than once. */\nexport function validateBackgroundDefs(defs: BackgroundDefs): void {\n for (const [name, def] of Object.entries(defs)) {\n if (typeof def.handler !== 'function') {\n throw new Error(`[bunderstack] background task \"${name}\" has no handler`)\n }\n if (def.kind === 'job' && name.startsWith(CRON_PREFIX)) {\n throw new Error(\n `[bunderstack] job \"${name}\": the \"${CRON_PREFIX}\" prefix is reserved for cron tasks`,\n )\n }\n if (\n def.retries !== undefined &&\n (def.retries < 0 || !Number.isInteger(def.retries))\n ) {\n throw new Error(\n `[bunderstack] background task \"${name}\": retries must be a non-negative integer`,\n )\n }\n if (def.timeout !== undefined && def.leaseDuration !== undefined) {\n throw new Error(\n `[bunderstack] background task \"${name}\": timeout and leaseDuration cannot both be declared`,\n )\n }\n for (const field of ['timeout', 'leaseDuration', 'maxRuntime'] as const) {\n const value = def[field]\n if (\n value !== undefined &&\n (!Number.isFinite(value) || !Number.isInteger(value) || value <= 0)\n ) {\n throw new Error(\n `[bunderstack] background task \"${name}\": ${field} must be a positive finite integer`,\n )\n }\n }\n if (def.kind === 'cron') {\n parseCron(def.schedule)\n assertCronHasNoDedupeUntil(def, `cron \"${name}\"`)\n if ((def as { concurrency?: number }).concurrency !== undefined) {\n throw new Error(\n `[bunderstack] cron \"${name}\": concurrency is not supported for cron tasks — slots are already unique`,\n )\n }\n if (def.catchUpWindow !== undefined && def.catchUpWindow <= 0) {\n throw new Error(\n `[bunderstack] cron \"${name}\": catchUpWindow must be positive`,\n )\n }\n continue\n }\n if (\n def.concurrency !== undefined &&\n (def.concurrency < 1 || !Number.isInteger(def.concurrency))\n ) {\n throw new Error(\n `[bunderstack] job \"${name}\": concurrency must be a positive integer`,\n )\n }\n if (\n def.dedupeUntil !== undefined &&\n def.dedupeUntil !== 'start' &&\n def.dedupeUntil !== 'finish'\n ) {\n throw new Error(\n `[bunderstack] job \"${name}\": dedupeUntil must be 'start' or 'finish'`,\n )\n }\n }\n}\n\n/** Cron slot ownership depends on the retained dedupe key. */\nfunction assertCronHasNoDedupeUntil(def: object, label: string): void {\n if ((def as { dedupeUntil?: unknown }).dedupeUntil !== undefined) {\n throw new Error(\n `[bunderstack] ${label}: dedupeUntil is not supported for cron tasks — cron tasks retain their slot key`,\n )\n }\n}\n\n/** @deprecated Use validateBackgroundDefs. */\nexport const validateJobsDefs = validateBackgroundDefs\n\n/**\n * Delay in ms before retry `attempt` (1-based = the attempt that just failed).\n * Jittered by ±20% so a shared outage does not retry every job in lockstep.\n * A caller-supplied backoff function is returned verbatim — the caller owns it.\n */\nexport function backoffMs(\n def: AnyBackgroundDefinition,\n attempt: number,\n): number {\n const b = def.backoff\n if (typeof b === 'function') return b(attempt)\n const baseMs = b?.baseMs ?? 1000\n const factor = b?.factor ?? 2\n const flat = baseMs * factor ** (attempt - 1)\n return Math.round(flat * (0.8 + Math.random() * 0.4))\n}\n\n/**\n * Build the `j` instance bunderstack hands to the config's `jobs` builder\n * callback (and exports for multi-file job setups).\n */\nexport function createJobsBuilder<\n TSchema extends Record<string, unknown>,\n TEnvResult = Record<string, unknown>,\n TMessaging extends MessagingConfig | undefined = MessagingConfig,\n>() {\n return {\n /** Identity with inference: pins TInput from the schema output. */\n job<TInput = undefined>(\n def: Omit<\n QueueJobDefinition<TInput, TSchema, TEnvResult, TMessaging>,\n 'kind'\n >,\n ): QueueJobDefinition<TInput, TSchema, TEnvResult, TMessaging> {\n return { kind: 'job', ...def }\n },\n cron<const TSchedule extends string>(\n def: Omit<\n CronDefinition<TSchema, TEnvResult, TSchedule, TMessaging>,\n 'kind'\n >,\n ): CronDefinition<TSchema, TEnvResult, TSchedule, TMessaging> {\n parseCron(def.schedule)\n assertCronHasNoDedupeUntil(def, 'cron')\n return { kind: 'cron', ...def }\n },\n /** Identity with validation: returns the defs map, typed. */\n define<TDefs extends BackgroundDefs>(defs: TDefs): TDefs {\n validateBackgroundDefs(defs)\n return defs\n },\n }\n}\n\n/** Type of the `j` instance — for builder callbacks declared in separate files. */\nexport type BunderstackJobsBuilder<\n TSchema extends Record<string, unknown>,\n TEnvResult = Record<string, unknown>,\n TMessaging extends MessagingConfig | undefined = MessagingConfig,\n> = ReturnType<typeof createJobsBuilder<TSchema, TEnvResult, TMessaging>>\n\n// Infers TInput from the JobDefinition's own type argument rather than\n// pattern-matching the (optional, so union-with-undefined) `input` property —\n// A required-property pattern fails structurally because `input` is optional,\n// so infer from the definition's own type argument instead.\ntype JobInputOf<TDef> =\n TDef extends QueueJobDefinition<infer TInput, any, any, any>\n ? TInput\n : undefined\n\n/**\n * `app.jobs`: `enqueue` narrowed to declared names + payloads. `Omit`s the\n * runtime facade's loose `enqueue` first — intersecting two same-named\n * methods instead would make TS treat them as overloaded, so the loose\n * `(name: string, ...)` signature would still accept any name.\n */\nexport type JobsFacade<\n TDefs extends JobsDefs,\n TSchema extends Record<string, unknown> | undefined = undefined,\n> = Omit<JobsRuntimeFacade, 'enqueue'> & {\n enqueue<K extends QueueJobKeys<TDefs>>(\n name: K,\n ...rest: JobInputOf<TDefs[K]> extends undefined\n ? [input?: undefined, opts?: JobsFacadeEnqueueOptions<TSchema>]\n : [input: JobInputOf<TDefs[K]>, opts?: JobsFacadeEnqueueOptions<TSchema>]\n ): Promise<{ id: string }>\n}\n\ntype JobsFacadeEnqueueOptions<\n TSchema extends Record<string, unknown> | undefined,\n> = [TSchema] extends [Record<string, unknown>]\n ? TypedEnqueueOptions<TSchema>\n : EnqueueOptions\n"]}
|
package/dist/jobs/index.d.ts
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
export { createJobsBuilder, validateBackgroundDefs, validateJobsDefs, DEFAULT_RETRIES, DEFAULT_LEASE_DURATION_MS, DEFAULT_TIMEOUT_MS, leaseDurationFor, } from './define.js';
|
|
2
2
|
export type { AnyJobDefinition, BackgroundTiming, BackgroundDefinition, BackgroundDefs, BunderstackJobContext, BunderstackJobsBuilder, DedupeUntil, EnqueueOptions, EnqueueTransaction, JobContext, JobDefinition, QueueJobDefinition, CronDefinition, CronInvocation, QueueJobKeys, TypedEnqueueOptions, JobsDefs, JobsFacade, JobsRuntimeFacade, } from './define.js';
|
|
3
|
-
export { enqueueJob, enqueueTarget } from './queue.js';
|
|
3
|
+
export { enqueueJob, enqueueTarget, resolveRunAt } from './queue.js';
|
|
4
4
|
export { createJobRunner } from './worker.js';
|
|
5
|
-
export { startJobWorker } from './runtime.js';
|
|
6
|
-
export type { StartWorkerOptions, RunWorkerOptions, WorkerCycleResult, WorkerHandle, } from './runtime.js';
|
|
7
5
|
export { parseCron, cronMatches } from './cron.js';
|
|
8
|
-
export { slotsDue, floorSlot, CRON_PREFIX, SLOT_MS } from './slots.js';
|
|
6
|
+
export { slotsDue, floorSlot, nextCronSlot, CRON_PREFIX, SLOT_MS, } from './slots.js';
|
|
9
7
|
export type { CatchUp } from './slots.js';
|
|
10
8
|
export type { TickResult } from './define.js';
|
|
11
9
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/jobs/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/jobs/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,iBAAiB,EACjB,sBAAsB,EACtB,gBAAgB,EAChB,eAAe,EACf,yBAAyB,EACzB,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,UAAU,CAAA;AACjB,YAAY,EACV,gBAAgB,EAChB,gBAAgB,EAChB,oBAAoB,EACpB,cAAc,EACd,qBAAqB,EACrB,sBAAsB,EACtB,WAAW,EACX,cAAc,EACd,kBAAkB,EAClB,UAAU,EACV,aAAa,EACb,kBAAkB,EAClB,cAAc,EACd,cAAc,EACd,YAAY,EACZ,mBAAmB,EACnB,QAAQ,EACR,UAAU,EACV,iBAAiB,GAClB,MAAM,UAAU,CAAA;AACjB,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/jobs/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,iBAAiB,EACjB,sBAAsB,EACtB,gBAAgB,EAChB,eAAe,EACf,yBAAyB,EACzB,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,UAAU,CAAA;AACjB,YAAY,EACV,gBAAgB,EAChB,gBAAgB,EAChB,oBAAoB,EACpB,cAAc,EACd,qBAAqB,EACrB,sBAAsB,EACtB,WAAW,EACX,cAAc,EACd,kBAAkB,EAClB,UAAU,EACV,aAAa,EACb,kBAAkB,EAClB,cAAc,EACd,cAAc,EACd,YAAY,EACZ,mBAAmB,EACnB,QAAQ,EACR,UAAU,EACV,iBAAiB,GAClB,MAAM,UAAU,CAAA;AACjB,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AACjE,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAC1C,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAA;AAC/C,OAAO,EACL,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,WAAW,EACX,OAAO,GACR,MAAM,SAAS,CAAA;AAChB,YAAY,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AACtC,YAAY,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA"}
|
package/dist/jobs/index.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
// src/jobs/index.ts — module surface consumed by bunderstack.
|
|
2
2
|
export { createJobsBuilder, validateBackgroundDefs, validateJobsDefs, DEFAULT_RETRIES, DEFAULT_LEASE_DURATION_MS, DEFAULT_TIMEOUT_MS, leaseDurationFor, } from './define.js';
|
|
3
|
-
export { enqueueJob, enqueueTarget } from './queue.js';
|
|
3
|
+
export { enqueueJob, enqueueTarget, resolveRunAt } from './queue.js';
|
|
4
4
|
export { createJobRunner } from './worker.js';
|
|
5
|
-
export { startJobWorker } from './runtime.js';
|
|
6
5
|
export { parseCron, cronMatches } from './cron.js';
|
|
7
|
-
export { slotsDue, floorSlot, CRON_PREFIX, SLOT_MS } from './slots.js';
|
|
6
|
+
export { slotsDue, floorSlot, nextCronSlot, CRON_PREFIX, SLOT_MS, } from './slots.js';
|
|
8
7
|
//# sourceMappingURL=index.js.map
|
package/dist/jobs/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/jobs/index.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAC9D,OAAO,EACL,iBAAiB,EACjB,sBAAsB,EACtB,gBAAgB,EAChB,eAAe,EACf,yBAAyB,EACzB,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,UAAU,CAAA;AAsBjB,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/jobs/index.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAC9D,OAAO,EACL,iBAAiB,EACjB,sBAAsB,EACtB,gBAAgB,EAChB,eAAe,EACf,yBAAyB,EACzB,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,UAAU,CAAA;AAsBjB,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AACjE,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAC1C,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAA;AAC/C,OAAO,EACL,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,WAAW,EACX,OAAO,GACR,MAAM,SAAS,CAAA","sourcesContent":["// src/jobs/index.ts — module surface consumed by bunderstack.\nexport {\n createJobsBuilder,\n validateBackgroundDefs,\n validateJobsDefs,\n DEFAULT_RETRIES,\n DEFAULT_LEASE_DURATION_MS,\n DEFAULT_TIMEOUT_MS,\n leaseDurationFor,\n} from './define'\nexport type {\n AnyJobDefinition,\n BackgroundTiming,\n BackgroundDefinition,\n BackgroundDefs,\n BunderstackJobContext,\n BunderstackJobsBuilder,\n DedupeUntil,\n EnqueueOptions,\n EnqueueTransaction,\n JobContext,\n JobDefinition,\n QueueJobDefinition,\n CronDefinition,\n CronInvocation,\n QueueJobKeys,\n TypedEnqueueOptions,\n JobsDefs,\n JobsFacade,\n JobsRuntimeFacade,\n} from './define'\nexport { enqueueJob, enqueueTarget, resolveRunAt } from './queue'\nexport { createJobRunner } from './worker'\nexport { parseCron, cronMatches } from './cron'\nexport {\n slotsDue,\n floorSlot,\n nextCronSlot,\n CRON_PREFIX,\n SLOT_MS,\n} from './slots'\nexport type { CatchUp } from './slots'\nexport type { TickResult } from './define'\n"]}
|
package/dist/jobs/queue.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ import type { EnqueueOptions, JobsDefs } from './define.js';
|
|
|
8
8
|
* detected cheaply and is unsupported.
|
|
9
9
|
*/
|
|
10
10
|
export declare function enqueueTarget(db: AnyDb, tx: AnyDb | undefined): AnyDb;
|
|
11
|
+
export declare function resolveRunAt(opts: EnqueueOptions, now: number): number;
|
|
11
12
|
export declare function enqueueJob(db: AnyDb, defs: JobsDefs, name: string, input: unknown, opts?: EnqueueOptions, now?: number): Promise<{
|
|
12
13
|
id: string;
|
|
13
14
|
}>;
|
package/dist/jobs/queue.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["../../src/jobs/queue.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,KAAK,EAAW,MAAM,YAAY,CAAA;AAChD,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAaxD;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,GAAG,SAAS,GAAG,KAAK,CAQrE;AAED,wBAAsB,UAAU,CAC9B,EAAE,EAAE,KAAK,EACT,IAAI,EAAE,QAAQ,EACd,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,OAAO,EACd,IAAI,GAAE,cAAmB,EACzB,GAAG,GAAE,MAAmB,GACvB,OAAO,CAAC;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["../../src/jobs/queue.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,KAAK,EAAW,MAAM,YAAY,CAAA;AAChD,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAaxD;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,GAAG,SAAS,GAAG,KAAK,CAQrE;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAItE;AAED,wBAAsB,UAAU,CAC9B,EAAE,EAAE,KAAK,EACT,IAAI,EAAE,QAAQ,EACd,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,OAAO,EACd,IAAI,GAAE,cAAmB,EACzB,GAAG,GAAE,MAAmB,GACvB,OAAO,CAAC;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC,CA6CzB"}
|
package/dist/jobs/queue.js
CHANGED
|
@@ -28,6 +28,11 @@ export function enqueueTarget(db, tx) {
|
|
|
28
28
|
}
|
|
29
29
|
return tx;
|
|
30
30
|
}
|
|
31
|
+
export function resolveRunAt(opts, now) {
|
|
32
|
+
return opts.runAt !== undefined
|
|
33
|
+
? new Date(opts.runAt).getTime()
|
|
34
|
+
: now + (opts.delay ?? 0);
|
|
35
|
+
}
|
|
31
36
|
export async function enqueueJob(db, defs, name, input, opts = {}, now = Date.now()) {
|
|
32
37
|
const def = defs[name];
|
|
33
38
|
if (!def) {
|
|
@@ -42,9 +47,7 @@ export async function enqueueJob(db, defs, name, input, opts = {}, now = Date.no
|
|
|
42
47
|
? validateStandardSchema(def.input, input, `job "${name}" input`)
|
|
43
48
|
: null;
|
|
44
49
|
const t = jobsTableFor(db);
|
|
45
|
-
const runAt = opts
|
|
46
|
-
? new Date(opts.runAt).getTime()
|
|
47
|
-
: now + (opts.delay ?? 0);
|
|
50
|
+
const runAt = resolveRunAt(opts, now);
|
|
48
51
|
// Two rounds cover the race where the deduping row reaches a terminal state
|
|
49
52
|
// (clearing its key) between our failed insert and our read.
|
|
50
53
|
for (let round = 0; round < 2; round++) {
|
package/dist/jobs/queue.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queue.js","sourceRoot":"","sources":["../../src/jobs/queue.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAChD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAK5D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACjD,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAA;AAC3D,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAErC,SAAS,aAAa,CAAC,MAAe;IACpC,IAAI,EAAE,CAAC,MAAM,EAAE,UAAU,CAAC;QAAE,OAAO,IAAI,CAAA;IACvC,IAAI,EAAE,CAAC,MAAM,EAAE,kBAAkB,CAAC;QAAE,OAAO,QAAQ,CAAA;IACnD,OAAO,SAAS,CAAA;AAClB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAC,EAAS,EAAE,EAAqB;IAC5D,IAAI,EAAE,KAAK,SAAS;QAAE,OAAO,EAAE,CAAA;IAC/B,IAAI,aAAa,CAAC,EAAE,CAAC,KAAK,aAAa,CAAC,EAAE,CAAC,EAAE,CAAC;QAC5C,MAAM,IAAI,KAAK,CACb,kEAAkE,CACnE,CAAA;IACH,CAAC;IACD,OAAO,EAAE,CAAA;AACX,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,EAAS,EACT,IAAc,EACd,IAAY,EACZ,KAAc,EACd,OAAuB,EAAE,EACzB,MAAc,IAAI,CAAC,GAAG,EAAE;IAExB,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,CAAA;IACtB,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CAAC,0CAA0C,IAAI,GAAG,CAAC,CAAA;IACpE,CAAC;IACD,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,KAAK,MAAM,CAAA;IAClC,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,WAAW,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAA;IACpD,4EAA4E;IAC5E,MAAM,MAAM,GAAG,MAAM;QACnB,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,GAAG,CAAC,KAAK;YACT,CAAC,CAAC,sBAAsB,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,IAAI,SAAS,CAAC;YACjE,CAAC,CAAC,IAAI,CAAA;IACV,MAAM,CAAC,GAAG,YAAY,CAAC,EAAE,CAAC,CAAA;IAC1B,MAAM,KAAK,
|
|
1
|
+
{"version":3,"file":"queue.js","sourceRoot":"","sources":["../../src/jobs/queue.ts"],"names":[],"mappings":"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","sourcesContent":["// src/jobs/queue.ts — durable enqueue with constraint-backed dedupe.\nimport { and, eq, is } from 'drizzle-orm'\nimport { PgDatabase } from 'drizzle-orm/pg-core'\nimport { BaseSQLiteDatabase } from 'drizzle-orm/sqlite-core'\n\nimport type { AnyDb, Dialect } from '../dialect'\nimport type { EnqueueOptions, JobsDefs } from './define'\n\nimport { jobsTableFor } from '../internal-tables'\nimport { validateStandardSchema } from '../standard-schema'\nimport { generate } from '../typeid'\nimport { CRON_PREFIX } from './slots'\n\nfunction handleDialect(handle: unknown): Dialect | undefined {\n if (is(handle, PgDatabase)) return 'pg'\n if (is(handle, BaseSQLiteDatabase)) return 'sqlite'\n return undefined\n}\n\n/**\n * The handle an enqueue inserts through: the caller's transaction when given,\n * otherwise the app database. Drizzle transactions extend their dialect's\n * database class, so the internal jobs table resolves the same way for both.\n * A transaction from an unrelated connection of the same dialect cannot be\n * detected cheaply and is unsupported.\n */\nexport function enqueueTarget(db: AnyDb, tx: AnyDb | undefined): AnyDb {\n if (tx === undefined) return db\n if (handleDialect(tx) !== handleDialect(db)) {\n throw new Error(\n '[bunderstack] enqueue tx belongs to a different database dialect',\n )\n }\n return tx\n}\n\nexport function resolveRunAt(opts: EnqueueOptions, now: number): number {\n return opts.runAt !== undefined\n ? new Date(opts.runAt).getTime()\n : now + (opts.delay ?? 0)\n}\n\nexport async function enqueueJob(\n db: AnyDb,\n defs: JobsDefs,\n name: string,\n input: unknown,\n opts: EnqueueOptions = {},\n now: number = Date.now(),\n): Promise<{ id: string }> {\n const def = defs[name]\n if (!def) {\n throw new Error(`[bunderstack] unknown background task \"${name}\"`)\n }\n const isCron = def.kind === 'cron'\n const type = isCron ? `${CRON_PREFIX}${name}` : name\n // Cron slots carry no payload; queue jobs validate theirs at the call site.\n const parsed = isCron\n ? null\n : def.input\n ? validateStandardSchema(def.input, input, `job \"${name}\" input`)\n : null\n const t = jobsTableFor(db)\n const runAt = resolveRunAt(opts, now)\n\n // Two rounds cover the race where the deduping row reaches a terminal state\n // (clearing its key) between our failed insert and our read.\n for (let round = 0; round < 2; round++) {\n const id = generate('job')\n const insertedRows = await db\n .insert(t)\n .values({\n id,\n type,\n payloadJson: JSON.stringify(parsed),\n status: 'pending',\n attempts: 0,\n runAt,\n dedupeKey: opts.dedupeKey ?? null,\n createdAt: now,\n })\n .onConflictDoNothing({ target: [t.type, t.dedupeKey] })\n .returning({ id: t.id })\n if (insertedRows[0]) return { id: String(insertedRows[0].id) }\n const existing = await db\n .select({ id: t.id })\n .from(t)\n .where(and(eq(t.type, type), eq(t.dedupeKey, opts.dedupeKey ?? '')))\n .limit(1)\n if (existing[0]) return { id: String(existing[0].id) }\n }\n throw new Error(\n `[bunderstack] enqueue of \"${name}\" lost a dedupe race twice — please retry`,\n )\n}\n"]}
|
package/dist/jobs/slots.d.ts
CHANGED
|
@@ -22,4 +22,9 @@ export declare function slotsDue(args: {
|
|
|
22
22
|
catchUp?: CatchUp;
|
|
23
23
|
catchUpWindowMs?: number;
|
|
24
24
|
}): number[];
|
|
25
|
+
/**
|
|
26
|
+
* The first slot matching `cron` in `(after, until]`, or null. A scheduler
|
|
27
|
+
* uses it to set its next alarm; `until` bounds the search.
|
|
28
|
+
*/
|
|
29
|
+
export declare function nextCronSlot(cron: ParsedCron, after: number, until: number): number | null;
|
|
25
30
|
//# sourceMappingURL=slots.d.ts.map
|
package/dist/jobs/slots.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slots.d.ts","sourceRoot":"","sources":["../../src/jobs/slots.ts"],"names":[],"mappings":"AACA,OAAO,EAAe,KAAK,UAAU,EAAE,MAAM,QAAQ,CAAA;AAErD,+EAA+E;AAC/E,eAAO,MAAM,OAAO,QAAS,CAAA;AAE7B,qDAAqD;AACrD,eAAO,MAAM,WAAW,UAAU,CAAA;AAElC,mDAAmD;AACnD,eAAO,MAAM,0BAA0B,QAAe,CAAA;AAEtD,MAAM,MAAM,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAA;AAEtC,+CAA+C;AAC/C,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAE5C;AAED;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE;IAC7B,IAAI,EAAE,UAAU,CAAA;IAChB,IAAI,EAAE,MAAM,CAAA;IACZ,EAAE,EAAE,MAAM,CAAA;IACV,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,eAAe,CAAC,EAAE,MAAM,CAAA;CACzB,GAAG,MAAM,EAAE,CAmBX"}
|
|
1
|
+
{"version":3,"file":"slots.d.ts","sourceRoot":"","sources":["../../src/jobs/slots.ts"],"names":[],"mappings":"AACA,OAAO,EAAe,KAAK,UAAU,EAAE,MAAM,QAAQ,CAAA;AAErD,+EAA+E;AAC/E,eAAO,MAAM,OAAO,QAAS,CAAA;AAE7B,qDAAqD;AACrD,eAAO,MAAM,WAAW,UAAU,CAAA;AAElC,mDAAmD;AACnD,eAAO,MAAM,0BAA0B,QAAe,CAAA;AAEtD,MAAM,MAAM,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAA;AAEtC,+CAA+C;AAC/C,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAE5C;AAED;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE;IAC7B,IAAI,EAAE,UAAU,CAAA;IAChB,IAAI,EAAE,MAAM,CAAA;IACZ,EAAE,EAAE,MAAM,CAAA;IACV,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,eAAe,CAAC,EAAE,MAAM,CAAA;CACzB,GAAG,MAAM,EAAE,CAmBX;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,UAAU,EAChB,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,GACZ,MAAM,GAAG,IAAI,CAMf"}
|
package/dist/jobs/slots.js
CHANGED
|
@@ -38,4 +38,16 @@ export function slotsDue(args) {
|
|
|
38
38
|
}
|
|
39
39
|
return slots;
|
|
40
40
|
}
|
|
41
|
+
/**
|
|
42
|
+
* The first slot matching `cron` in `(after, until]`, or null. A scheduler
|
|
43
|
+
* uses it to set its next alarm; `until` bounds the search.
|
|
44
|
+
*/
|
|
45
|
+
export function nextCronSlot(cron, after, until) {
|
|
46
|
+
const last = floorSlot(until);
|
|
47
|
+
for (let s = floorSlot(after) + SLOT_MS; s <= last; s += SLOT_MS) {
|
|
48
|
+
if (cronMatches(cron, s))
|
|
49
|
+
return s;
|
|
50
|
+
}
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
41
53
|
//# sourceMappingURL=slots.js.map
|
package/dist/jobs/slots.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slots.js","sourceRoot":"","sources":["../../src/jobs/slots.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,OAAO,EAAE,WAAW,EAAmB,MAAM,QAAQ,CAAA;AAErD,+EAA+E;AAC/E,MAAM,CAAC,MAAM,OAAO,GAAG,MAAM,CAAA;AAE7B,qDAAqD;AACrD,MAAM,CAAC,MAAM,WAAW,GAAG,OAAO,CAAA;AAElC,mDAAmD;AACnD,MAAM,CAAC,MAAM,0BAA0B,GAAG,EAAE,GAAG,OAAO,CAAA;AAItD,+CAA+C;AAC/C,MAAM,UAAU,SAAS,CAAC,EAAU;IAClC,OAAO,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,OAAO,CAAC,GAAG,OAAO,CAAA;AAC3C,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,QAAQ,CAAC,IAMxB;IACC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,QAAQ,CAAA;IACxC,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,IAAI,0BAA0B,CAAA;IACnE,MAAM,EAAE,GAAG,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IAC7B,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,GAAG,QAAQ,CAAC,CAAA;IAC1D,IAAI,EAAE,IAAI,IAAI;QAAE,OAAO,EAAE,CAAA;IAEzB,IAAI,OAAO,KAAK,QAAQ,EAAE,CAAC;QACzB,KAAK,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,IAAI,OAAO,EAAE,CAAC;YACxC,IAAI,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;gBAAE,OAAO,CAAC,CAAC,CAAC,CAAA;QAC3C,CAAC;QACD,OAAO,EAAE,CAAA;IACX,CAAC;IAED,MAAM,KAAK,GAAa,EAAE,CAAA;IAC1B,KAAK,IAAI,CAAC,GAAG,IAAI,GAAG,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,OAAO,EAAE,CAAC;QACnD,IAAI,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;YAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IAC9C,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC","sourcesContent":["// src/jobs/slots.ts — cron slot enumeration. Pure; no db, no clock reads.\nimport { cronMatches, type ParsedCron } from './cron'\n\n/** Slot granularity. Every slot timestamp satisfies `slot % SLOT_MS === 0`. */\nexport const SLOT_MS = 60_000\n\n/** Reserved job-type prefix for cron occurrences. */\nexport const CRON_PREFIX = 'cron:'\n\n/** How far back either catch-up mode will look. */\nexport const DEFAULT_CATCH_UP_WINDOW_MS = 60 * SLOT_MS\n\nexport type CatchUp = 'latest' | 'all'\n\n/** Aligns `ms` down to its containing slot. */\nexport function floorSlot(ms: number): number {\n return Math.floor(ms / SLOT_MS) * SLOT_MS\n}\n\n/**\n * Slots matching `cron` in the half-open range `(from, to]`, oldest first.\n *\n * `from` is exclusive so a stored watermark is never re-emitted. Both modes are\n * clamped to `catchUpWindowMs` — without it a watermark far in the past would\n * make this iterate unbounded minutes.\n */\nexport function slotsDue(args: {\n cron: ParsedCron\n from: number\n to: number\n catchUp?: CatchUp\n catchUpWindowMs?: number\n}): number[] {\n const catchUp = args.catchUp ?? 'latest'\n const windowMs = args.catchUpWindowMs ?? DEFAULT_CATCH_UP_WINDOW_MS\n const to = floorSlot(args.to)\n const from = Math.max(floorSlot(args.from), to - windowMs)\n if (to <= from) return []\n\n if (catchUp === 'latest') {\n for (let s = to; s > from; s -= SLOT_MS) {\n if (cronMatches(args.cron, s)) return [s]\n }\n return []\n }\n\n const slots: number[] = []\n for (let s = from + SLOT_MS; s <= to; s += SLOT_MS) {\n if (cronMatches(args.cron, s)) slots.push(s)\n }\n return slots\n}\n"]}
|
|
1
|
+
{"version":3,"file":"slots.js","sourceRoot":"","sources":["../../src/jobs/slots.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,OAAO,EAAE,WAAW,EAAmB,MAAM,QAAQ,CAAA;AAErD,+EAA+E;AAC/E,MAAM,CAAC,MAAM,OAAO,GAAG,MAAM,CAAA;AAE7B,qDAAqD;AACrD,MAAM,CAAC,MAAM,WAAW,GAAG,OAAO,CAAA;AAElC,mDAAmD;AACnD,MAAM,CAAC,MAAM,0BAA0B,GAAG,EAAE,GAAG,OAAO,CAAA;AAItD,+CAA+C;AAC/C,MAAM,UAAU,SAAS,CAAC,EAAU;IAClC,OAAO,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,OAAO,CAAC,GAAG,OAAO,CAAA;AAC3C,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,QAAQ,CAAC,IAMxB;IACC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,QAAQ,CAAA;IACxC,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,IAAI,0BAA0B,CAAA;IACnE,MAAM,EAAE,GAAG,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IAC7B,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,GAAG,QAAQ,CAAC,CAAA;IAC1D,IAAI,EAAE,IAAI,IAAI;QAAE,OAAO,EAAE,CAAA;IAEzB,IAAI,OAAO,KAAK,QAAQ,EAAE,CAAC;QACzB,KAAK,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,IAAI,OAAO,EAAE,CAAC;YACxC,IAAI,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;gBAAE,OAAO,CAAC,CAAC,CAAC,CAAA;QAC3C,CAAC;QACD,OAAO,EAAE,CAAA;IACX,CAAC;IAED,MAAM,KAAK,GAAa,EAAE,CAAA;IAC1B,KAAK,IAAI,CAAC,GAAG,IAAI,GAAG,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,OAAO,EAAE,CAAC;QACnD,IAAI,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;YAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IAC9C,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAC1B,IAAgB,EAChB,KAAa,EACb,KAAa;IAEb,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC,CAAA;IAC7B,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,OAAO,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,IAAI,OAAO,EAAE,CAAC;QACjE,IAAI,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC;YAAE,OAAO,CAAC,CAAA;IACpC,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC","sourcesContent":["// src/jobs/slots.ts — cron slot enumeration. Pure; no db, no clock reads.\nimport { cronMatches, type ParsedCron } from './cron'\n\n/** Slot granularity. Every slot timestamp satisfies `slot % SLOT_MS === 0`. */\nexport const SLOT_MS = 60_000\n\n/** Reserved job-type prefix for cron occurrences. */\nexport const CRON_PREFIX = 'cron:'\n\n/** How far back either catch-up mode will look. */\nexport const DEFAULT_CATCH_UP_WINDOW_MS = 60 * SLOT_MS\n\nexport type CatchUp = 'latest' | 'all'\n\n/** Aligns `ms` down to its containing slot. */\nexport function floorSlot(ms: number): number {\n return Math.floor(ms / SLOT_MS) * SLOT_MS\n}\n\n/**\n * Slots matching `cron` in the half-open range `(from, to]`, oldest first.\n *\n * `from` is exclusive so a stored watermark is never re-emitted. Both modes are\n * clamped to `catchUpWindowMs` — without it a watermark far in the past would\n * make this iterate unbounded minutes.\n */\nexport function slotsDue(args: {\n cron: ParsedCron\n from: number\n to: number\n catchUp?: CatchUp\n catchUpWindowMs?: number\n}): number[] {\n const catchUp = args.catchUp ?? 'latest'\n const windowMs = args.catchUpWindowMs ?? DEFAULT_CATCH_UP_WINDOW_MS\n const to = floorSlot(args.to)\n const from = Math.max(floorSlot(args.from), to - windowMs)\n if (to <= from) return []\n\n if (catchUp === 'latest') {\n for (let s = to; s > from; s -= SLOT_MS) {\n if (cronMatches(args.cron, s)) return [s]\n }\n return []\n }\n\n const slots: number[] = []\n for (let s = from + SLOT_MS; s <= to; s += SLOT_MS) {\n if (cronMatches(args.cron, s)) slots.push(s)\n }\n return slots\n}\n\n/**\n * The first slot matching `cron` in `(after, until]`, or null. A scheduler\n * uses it to set its next alarm; `until` bounds the search.\n */\nexport function nextCronSlot(\n cron: ParsedCron,\n after: number,\n until: number,\n): number | null {\n const last = floorSlot(until)\n for (let s = floorSlot(after) + SLOT_MS; s <= last; s += SLOT_MS) {\n if (cronMatches(cron, s)) return s\n }\n return null\n}\n"]}
|
package/dist/jobs/worker.d.ts
CHANGED
|
@@ -14,6 +14,12 @@ export declare function createJobRunner(deps: {
|
|
|
14
14
|
tick(now?: number): Promise<TickResult>;
|
|
15
15
|
pump: (now?: number) => Promise<PumpResult>;
|
|
16
16
|
drain: () => Promise<void>;
|
|
17
|
+
/**
|
|
18
|
+
* The earliest time that has work: a pending run_at, a running lease end,
|
|
19
|
+
* or a cron slot not yet materialized. Never earlier than `now`; null when
|
|
20
|
+
* nothing is due before `until`.
|
|
21
|
+
*/
|
|
22
|
+
nextDueAt(now: number, until: number): Promise<number | null>;
|
|
17
23
|
inspect(now: number): Promise<{
|
|
18
24
|
runnable: any;
|
|
19
25
|
failed: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../../src/jobs/worker.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AACvC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AACnD,OAAO,KAAK,EAEV,QAAQ,EACR,iBAAiB,EACjB,UAAU,EACX,MAAM,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../../src/jobs/worker.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AACvC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AACnD,OAAO,KAAK,EAEV,QAAQ,EACR,iBAAiB,EACjB,UAAU,EACX,MAAM,UAAU,CAAA;AA2DjB,KAAK,UAAU,GAAG;IAAE,IAAI,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAAA;AA8D1C,wBAAgB,eAAe,CAAC,IAAI,EAAE;IACpC,EAAE,EAAE,KAAK,CAAA;IACT,IAAI,EAAE,QAAQ,CAAA;IACd,4EAA4E;IAC5E,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC5B,MAAM,CAAC,EAAE,iBAAiB,CAAA;CAC3B;eAugBmB,MAAM,GAAgB,OAAO,CAAC,UAAU,CAAC;iBAnBlC,MAAM,KAAgB,OAAO,CAAC,UAAU,CAAC;iBAa1C,OAAO,CAAC,IAAI,CAAC;IAYnC;;;;OAIG;mBACkB,MAAM,SAAS,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;iBAyBhD,MAAM;;;;;;;;;;;;oBAiEb,SAAS,GACT,SAAS,GACT,WAAW,GACX,QAAQ;;;;;;;qBAQH,iBAAiB;EAIrC"}
|