@dxos/functions 0.5.2 → 0.5.3-main.088a2c8
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/dist/lib/browser/index.mjs +492 -146
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node/index.cjs +488 -143
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/types/src/handler.d.ts +33 -12
- package/dist/types/src/handler.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +1 -1
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/runtime/dev-server.d.ts +17 -6
- package/dist/types/src/runtime/dev-server.d.ts.map +1 -1
- package/dist/types/src/runtime/dev-server.test.d.ts +2 -0
- package/dist/types/src/runtime/dev-server.test.d.ts.map +1 -0
- package/dist/types/src/runtime/scheduler.d.ts +55 -7
- package/dist/types/src/runtime/scheduler.d.ts.map +1 -1
- package/dist/types/src/testing/test/handler.d.ts +3 -0
- package/dist/types/src/testing/test/handler.d.ts.map +1 -0
- package/dist/types/src/testing/test/index.d.ts +3 -0
- package/dist/types/src/testing/test/index.d.ts.map +1 -0
- package/dist/types/src/types.d.ts +182 -0
- package/dist/types/src/types.d.ts.map +1 -0
- package/dist/types/tools/schema.d.ts +2 -0
- package/dist/types/tools/schema.d.ts.map +1 -0
- package/package.json +20 -11
- package/schema/functions.json +183 -0
- package/src/handler.ts +56 -26
- package/src/index.ts +1 -1
- package/src/runtime/dev-server.test.ts +80 -0
- package/src/runtime/dev-server.ts +74 -40
- package/src/runtime/scheduler.test.ts +163 -9
- package/src/runtime/scheduler.ts +228 -64
- package/src/testing/test/handler.ts +9 -0
- package/src/testing/test/index.ts +7 -0
- package/src/types.ts +87 -0
- package/dist/types/src/manifest.d.ts +0 -26
- package/dist/types/src/manifest.d.ts.map +0 -1
- package/src/manifest.ts +0 -42
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../../../src/handler.ts", "../../../src/runtime/dev-server.ts", "../../../src/runtime/scheduler.ts"],
|
|
4
|
-
"sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport { type Client, PublicKey } from '@dxos/client';\nimport { type Space } from '@dxos/client/echo';\nimport { type EchoReactiveObject } from '@dxos/echo-schema';\nimport { log } from '@dxos/log';\nimport { nonNullable } from '@dxos/util';\n\n// TODO(burdon): No response?\nexport interface Response {\n status(code: number): Response;\n}\n\n// TODO(burdon): Limit access to individual space?\nexport interface FunctionContext {\n client: Client;\n dataDir?: string;\n}\n\n// TODO(burdon): Model after http request. Ref Lambda/OpenFaaS.\n// https://docs.aws.amazon.com/lambda/latest/dg/typescript-handler.html\nexport type FunctionHandler<T extends {}> = (params: {\n event: T;\n context: FunctionContext;\n response: Response;\n}) => Promise<Response | void>;\n\nexport type FunctionSubscriptionEvent = {\n space?: string; // TODO(burdon): Convert to PublicKey.\n objects?: string[];\n};\n\nexport type FunctionSubscriptionEvent2 = {\n space?: Space;\n objects?: EchoReactiveObject<any>[];\n};\n\n/**\n * Handler wrapper for subscription events; extracts space and objects.\n *\n * To test:\n * ```\n * curl -s -X POST -H \"Content-Type: application/json\" --data '{\"space\": \"0446...1cbb\"}' http://localhost:7100/dev/email-extractor\n * ```\n *\n * NOTE: Get space key from devtools or `dx space list --json`\n */\nexport const subscriptionHandler = (\n handler: FunctionHandler<FunctionSubscriptionEvent2>,\n): FunctionHandler<FunctionSubscriptionEvent> => {\n return ({ event, context, ...rest }) => {\n const { client } = context;\n const space = event.space ? client.spaces.get(PublicKey.from(event.space)) : undefined;\n const objects =\n space &&\n event.objects?.map<EchoReactiveObject<any> | undefined>((id) => space!.db.getObjectById(id)).filter(nonNullable);\n\n if (!!event.space && !space) {\n log.warn('invalid space', { event });\n } else {\n log.info('handler', { space: space?.key.truncate(), objects: objects?.length });\n }\n\n return handler({ event: { space, objects }, context, ...rest });\n };\n};\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport express from 'express';\nimport { getPort } from 'get-port-please';\nimport type http from 'http';\nimport { join } from 'node:path';\n\nimport { Trigger } from '@dxos/async';\nimport { type Client } from '@dxos/client';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\n\nimport { type FunctionContext, type FunctionHandler, type Response } from '../handler';\nimport { type FunctionDef, type FunctionManifest } from '../manifest';\n\nexport type DevServerOptions = {\n port?: number;\n directory: string;\n manifest: FunctionManifest;\n reload?: boolean;\n dataDir?: string;\n};\n\n/**\n * Functions dev server provides a local HTTP server for testing functions.\n */\nexport class DevServer {\n // Function handlers indexed by name (URL path).\n private readonly _handlers: Record<string, { def: FunctionDef; handler: FunctionHandler<any> }> = {};\n\n private _server?: http.Server;\n private _port?: number;\n private _registrationId?: string;\n private _proxy?: string;\n private _seq = 0;\n\n // prettier-ignore\n constructor(\n private readonly _client: Client,\n private readonly _options: DevServerOptions,\n ) {}\n\n get endpoint() {\n invariant(this._port);\n return `http://localhost:${this._port}`;\n }\n\n get proxy() {\n return this._proxy;\n }\n\n get functions() {\n return Object.values(this._handlers);\n }\n\n async initialize() {\n for (const def of this._options.manifest.functions) {\n try {\n await this._load(def);\n } catch (err) {\n log.error('parsing function (check manifest)', err);\n }\n }\n }\n\n async start() {\n const app = express();\n app.use(express.json());\n\n app.post('/:name', async (req, res) => {\n const { name } = req.params;\n try {\n log.info('calling', { name });\n if (this._options.reload) {\n const { def } = this._handlers[name];\n await this._load(def, true);\n }\n\n res.statusCode = await this._invoke(name, req.body);\n res.end();\n } catch (err: any) {\n log.catch(err);\n res.statusCode = 500;\n res.end();\n }\n });\n\n this._port = await getPort({ host: 'localhost', port: 7200, portRange: [7200, 7299] });\n this._server = app.listen(this._port);\n\n try {\n // Register functions.\n const { registrationId, endpoint } = await this._client.services.services.FunctionRegistryService!.register({\n endpoint: this.endpoint,\n functions: this.functions.map(({ def: { name } }) => ({ name })),\n });\n\n log.info('registered', { registrationId, endpoint });\n this._registrationId = registrationId;\n this._proxy = endpoint;\n } catch (err: any) {\n await this.stop();\n throw new Error('FunctionRegistryService not available (check plugin is configured).');\n }\n }\n\n async stop() {\n const trigger = new Trigger();\n this._server?.close(async () => {\n if (this._registrationId) {\n await this._client.services.services.FunctionRegistryService!.unregister({\n registrationId: this._registrationId,\n });\n\n log.info('unregistered', { registrationId: this._registrationId });\n this._registrationId = undefined;\n this._proxy = undefined;\n }\n\n trigger.wake();\n });\n\n await trigger.wait();\n this._port = undefined;\n this._server = undefined;\n }\n\n /**\n * Load function.\n */\n private async _load(def: FunctionDef, flush = false) {\n const { id, name, handler } = def;\n const path = join(this._options.directory, handler);\n log.info('loading', { id });\n\n // Remove from cache.\n if (flush) {\n Object.keys(require.cache)\n .filter((key) => key.startsWith(path))\n .forEach((key) => delete require.cache[key]);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const module = require(path);\n if (typeof module.default !== 'function') {\n throw new Error(`Handler must export default function: ${id}`);\n }\n\n this._handlers[name] = { def, handler: module.default };\n }\n\n /**\n * Invoke function handler.\n */\n private async _invoke(name: string, event: any) {\n const seq = ++this._seq;\n const now = Date.now();\n\n log.info('req', { seq, name });\n const { handler } = this._handlers[name];\n\n const context: FunctionContext = {\n client: this._client,\n dataDir: this._options.dataDir,\n };\n\n let statusCode = 200;\n const response: Response = {\n status: (code: number) => {\n statusCode = code;\n return response;\n },\n };\n\n await handler({ context, event, response });\n log.info('res', { seq, name, statusCode, duration: Date.now() - now });\n\n return statusCode;\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { CronJob } from 'cron';\n\nimport { TextV0Type } from '@braneframe/types';\nimport { debounce, DeferredTask } from '@dxos/async';\nimport { type Client, type PublicKey } from '@dxos/client';\nimport { type Space, Filter, createSubscription, type Query, getAutomergeObjectCore } from '@dxos/client/echo';\nimport { Context } from '@dxos/context';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\nimport { ComplexMap } from '@dxos/util';\n\nimport { type FunctionSubscriptionEvent } from '../handler';\nimport { type FunctionDef, type FunctionManifest, type FunctionTrigger, type TriggerSubscription } from '../manifest';\n\ntype Callback = (data: FunctionSubscriptionEvent) => Promise<number>;\n\ntype SchedulerOptions = {\n endpoint?: string;\n callback?: Callback;\n};\n\n/**\n * Functions scheduler.\n */\n// TODO(burdon): Create tests.\nexport class Scheduler {\n // Map of mounted functions.\n private readonly _mounts = new ComplexMap<\n { id: string; spaceKey: PublicKey },\n { ctx: Context; trigger: FunctionTrigger }\n >(({ id, spaceKey }) => `${spaceKey.toHex()}:${id}`);\n\n constructor(\n private readonly _client: Client,\n private readonly _manifest: FunctionManifest,\n private readonly _options: SchedulerOptions = {},\n ) {}\n\n async start() {\n this._client.spaces.subscribe(async (spaces) => {\n for (const space of spaces) {\n await space.waitUntilReady();\n for (const trigger of this._manifest.triggers ?? []) {\n await this.mount(new Context(), space, trigger);\n }\n }\n });\n }\n\n async stop() {\n for (const { id, spaceKey } of this._mounts.keys()) {\n await this.unmount(id, spaceKey);\n }\n }\n\n private async mount(ctx: Context, space: Space, trigger: FunctionTrigger) {\n const key = { id: trigger.function, spaceKey: space.key };\n const def = this._manifest.functions.find((config) => config.id === trigger.function);\n invariant(def, `Function not found: ${trigger.function}`);\n\n // Currently supports only one trigger declaration per function.\n const exists = this._mounts.get(key);\n if (!exists) {\n this._mounts.set(key, { ctx, trigger });\n log('mount', { space: space.key, trigger });\n if (ctx.disposed) {\n return;\n }\n\n // Timer.\n if (trigger.schedule) {\n this._createTimer(ctx, space, def, trigger);\n }\n\n // Subscription.\n for (const triggerSubscription of trigger.subscriptions ?? []) {\n this._createSubscription(ctx, space, def, triggerSubscription);\n }\n }\n }\n\n private async unmount(id: string, spaceKey: PublicKey) {\n const key = { id, spaceKey };\n const { ctx } = this._mounts.get(key) ?? {};\n if (ctx) {\n this._mounts.delete(key);\n await ctx.dispose();\n }\n }\n\n private _createTimer(ctx: Context, space: Space, def: FunctionDef, trigger: FunctionTrigger) {\n const task = new DeferredTask(ctx, async () => {\n await this._execFunction(def, {\n space: space.key,\n });\n });\n\n invariant(trigger.schedule);\n let last = 0;\n let run = 0;\n // https://www.npmjs.com/package/cron#constructor\n const job = CronJob.from({\n cronTime: trigger.schedule,\n runOnInit: false,\n onTick: () => {\n // TODO(burdon): Check greater than 30s (use cron-parser).\n const now = Date.now();\n const delta = last ? now - last : 0;\n last = now;\n\n run++;\n log.info('tick', { space: space.key.truncate(), count: run, delta });\n task.schedule();\n },\n });\n\n job.start();\n ctx.onDispose(() => job.stop());\n }\n\n private _createSubscription(ctx: Context, space: Space, def: FunctionDef, triggerSubscription: TriggerSubscription) {\n log.info('subscription', { space: space.key, triggerSubscription });\n const objectIds = new Set<string>();\n const task = new DeferredTask(ctx, async () => {\n await this._execFunction(def, {\n space: space.key,\n objects: Array.from(objectIds),\n });\n });\n\n // TODO(burdon): Don't fire initially.\n // TODO(burdon): Standardize subscription handles.\n const subscriptions: (() => void)[] = [];\n const subscription = createSubscription(({ added, updated }) => {\n log.info('updated', { added: added.length, updated: updated.length });\n for (const object of added) {\n objectIds.add(object.id);\n }\n for (const object of updated) {\n objectIds.add(object.id);\n }\n\n task.schedule();\n });\n subscriptions.push(() => subscription.unsubscribe());\n\n // TODO(burdon): Create queue. Only allow one invocation per trigger at a time?\n // TODO(burdon): Disable trigger if keeps failing.\n const { type, props, deep, delay } = triggerSubscription;\n const update = ({ objects }: Query) => {\n subscription.update(objects);\n\n // TODO(burdon): Hack to monitor changes to Document's text object.\n if (deep) {\n log.info('update', { type, deep, objects: objects.length });\n for (const object of objects) {\n const content = object.content;\n if (content instanceof TextV0Type) {\n subscriptions.push(\n getAutomergeObjectCore(content).updates.on(debounce(() => subscription.update([object]), 1_000)),\n );\n }\n }\n }\n };\n\n // TODO(burdon): [Bug]: all callbacks are fired on the first mutation.\n // TODO(burdon): [Bug]: not updated when document is deleted (either top or hierarchically).\n const query = space.db.query(Filter.typename(type, props));\n subscriptions.push(query.subscribe(delay ? debounce(update, delay * 1_000) : update));\n\n ctx.onDispose(() => {\n subscriptions.forEach((unsubscribe) => unsubscribe());\n });\n }\n\n private async _execFunction(def: FunctionDef, data: any) {\n try {\n log('request', { function: def.id });\n const { endpoint, callback } = this._options;\n let status = 0;\n if (endpoint) {\n // TODO(burdon): Move out of scheduler (generalize as callback).\n const response = await fetch(`${this._options.endpoint}/${def.name}`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(data),\n });\n\n status = response.status;\n } else if (callback) {\n status = await callback(data);\n }\n\n // const result = await response.json();\n log('result', { function: def.id, result: status });\n } catch (err: any) {\n log.error('error', { function: def.id, error: err.message });\n }\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["PublicKey", "log", "nonNullable", "subscriptionHandler", "handler", "event", "context", "rest", "client", "space", "spaces", "get", "from", "undefined", "objects", "map", "id", "db", "getObjectById", "filter", "warn", "info", "key", "truncate", "length", "express", "getPort", "join", "Trigger", "invariant", "log", "DevServer", "constructor", "_client", "_options", "_handlers", "_seq", "endpoint", "invariant", "_port", "proxy", "_proxy", "functions", "Object", "values", "initialize", "def", "manifest", "_load", "err", "log", "error", "start", "app", "express", "use", "json", "post", "req", "res", "
|
|
3
|
+
"sources": ["../../../src/handler.ts", "../../../src/runtime/dev-server.ts", "../../../src/runtime/scheduler.ts", "../../../src/types.ts"],
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport { type Client, PublicKey } from '@dxos/client';\nimport { type Space } from '@dxos/client/echo';\nimport { type EchoReactiveObject } from '@dxos/echo-schema';\nimport { log } from '@dxos/log';\nimport { nonNullable } from '@dxos/util';\n\n// TODO(burdon): Model after http request. Ref Lambda/OpenFaaS.\n// https://docs.aws.amazon.com/lambda/latest/dg/typescript-handler.html\n// https://www.serverless.com/framework/docs/providers/aws/guide/serverless.yml/#functions\n// https://www.npmjs.com/package/aws-lambda\n\n/**\n * Function handler.\n */\nexport type FunctionHandler<TData = {}, TMeta = {}> = (params: {\n context: FunctionContext;\n event: FunctionEvent<TData, TMeta>;\n response: FunctionResponse;\n}) => Promise<FunctionResponse | void>;\n\n/**\n * Function context.\n */\nexport interface FunctionContext {\n // TODO(burdon): Limit access to individual space.\n client: Client;\n // TODO(burdon): Replace with storage service abstraction.\n dataDir?: string;\n}\n\n/**\n * Event payload.\n */\nexport type FunctionEvent<TData = {}, TMeta = {}> = {\n data: FunctionEventMeta<TMeta> & TData;\n};\n\n/**\n * Metadata from trigger.\n */\nexport type FunctionEventMeta<TMeta = {}> = {\n meta: TMeta;\n};\n\n/**\n * Function response.\n */\nexport interface FunctionResponse {\n status(code: number): FunctionResponse;\n}\n\n//\n// Subscription utils.\n//\n\nexport type RawSubscriptionData = {\n spaceKey?: string;\n objects?: string[];\n};\n\nexport type SubscriptionData = {\n space?: Space;\n objects?: EchoReactiveObject<any>[];\n};\n\n/**\n * Handler wrapper for subscription events; extracts space and objects.\n *\n * To test:\n * ```\n * curl -s -X POST -H \"Content-Type: application/json\" --data '{\"space\": \"0446...1cbb\"}' http://localhost:7100/dev/email-extractor\n * ```\n *\n * NOTE: Get space key from devtools or `dx space list --json`\n */\nexport const subscriptionHandler = <TMeta>(\n handler: FunctionHandler<SubscriptionData, TMeta>,\n): FunctionHandler<RawSubscriptionData, TMeta> => {\n return ({ event: { data }, context, ...rest }) => {\n const { client } = context;\n const space = data.spaceKey ? client.spaces.get(PublicKey.from(data.spaceKey)) : undefined;\n const objects = space\n ? data.objects?.map<EchoReactiveObject<any> | undefined>((id) => space!.db.getObjectById(id)).filter(nonNullable)\n : [];\n\n if (!!data.spaceKey && !space) {\n log.warn('invalid space', { data });\n } else {\n log.info('handler', { space: space?.key.truncate(), objects: objects?.length });\n }\n\n return handler({ event: { data: { ...data, space, objects } }, context, ...rest });\n };\n};\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport express from 'express';\nimport { getPort } from 'get-port-please';\nimport type http from 'http';\nimport { join } from 'node:path';\n\nimport { Event, Trigger } from '@dxos/async';\nimport { type Client } from '@dxos/client';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\n\nimport { type FunctionContext, type FunctionEvent, type FunctionHandler, type FunctionResponse } from '../handler';\nimport { type FunctionDef, type FunctionManifest } from '../types';\n\nexport type DevServerOptions = {\n manifest: FunctionManifest;\n baseDir: string;\n port?: number;\n reload?: boolean;\n dataDir?: string;\n};\n\n/**\n * Functions dev server provides a local HTTP server for testing functions.\n */\nexport class DevServer {\n // Function handlers indexed by name (URL path).\n private readonly _handlers: Record<string, { def: FunctionDef; handler: FunctionHandler<any> }> = {};\n\n private _server?: http.Server;\n private _port?: number;\n private _functionServiceRegistration?: string;\n private _proxy?: string;\n private _seq = 0;\n\n public readonly update = new Event<number>();\n\n // prettier-ignore\n constructor(\n private readonly _client: Client,\n private readonly _options: DevServerOptions,\n ) {}\n\n get stats() {\n return {\n seq: this._seq,\n };\n }\n\n get endpoint() {\n invariant(this._port);\n return `http://localhost:${this._port}`;\n }\n\n get proxy() {\n return this._proxy;\n }\n\n get functions() {\n return Object.values(this._handlers);\n }\n\n async initialize() {\n for (const def of this._options.manifest.functions) {\n try {\n await this._load(def);\n } catch (err) {\n log.error('parsing function (check manifest)', err);\n }\n }\n }\n\n async start() {\n invariant(!this._server);\n log.info('starting...');\n\n // TODO(burdon): Move to hono.\n const app = express();\n app.use(express.json());\n\n app.post('/:path', async (req, res) => {\n const { path } = req.params;\n try {\n log.info('calling', { path });\n if (this._options.reload) {\n const { def } = this._handlers['/' + path];\n await this._load(def, true);\n }\n\n // TODO(burdon): Get function context.\n res.statusCode = await this.invoke('/' + path, req.body);\n res.end();\n } catch (err: any) {\n log.catch(err);\n res.statusCode = 500;\n res.end();\n }\n });\n\n this._port = await getPort({ host: 'localhost', port: 7200, portRange: [7200, 7299] });\n this._server = app.listen(this._port);\n\n try {\n // Register functions.\n const { registrationId, endpoint } = await this._client.services.services.FunctionRegistryService!.register({\n endpoint: this.endpoint,\n functions: this.functions.map(({ def: { id, path } }) => ({ id, path })),\n });\n\n log.info('registered', { endpoint });\n this._proxy = endpoint;\n this._functionServiceRegistration = registrationId;\n } catch (err: any) {\n await this.stop();\n throw new Error('FunctionRegistryService not available (check plugin is configured).');\n }\n\n log.info('started', { port: this._port });\n }\n\n async stop() {\n invariant(this._server);\n log.info('stopping...');\n\n const trigger = new Trigger();\n this._server.close(async () => {\n log.info('server stopped');\n try {\n if (this._functionServiceRegistration) {\n invariant(this._client.services.services.FunctionRegistryService);\n await this._client.services.services.FunctionRegistryService.unregister({\n registrationId: this._functionServiceRegistration,\n });\n\n log.info('unregistered', { registrationId: this._functionServiceRegistration });\n this._functionServiceRegistration = undefined;\n this._proxy = undefined;\n }\n\n trigger.wake();\n } catch (err) {\n trigger.throw(err as Error);\n }\n });\n\n await trigger.wait();\n this._port = undefined;\n this._server = undefined;\n log.info('stopped');\n }\n\n /**\n * Load function.\n */\n private async _load(def: FunctionDef, force = false) {\n const { id, path, handler } = def;\n const filePath = join(this._options.baseDir, handler);\n log.info('loading', { id, force });\n\n // Remove from cache.\n if (force) {\n Object.keys(require.cache)\n .filter((key) => key.startsWith(filePath))\n .forEach((key) => {\n delete require.cache[key];\n });\n }\n\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const module = require(filePath);\n if (typeof module.default !== 'function') {\n throw new Error(`Handler must export default function: ${id}`);\n }\n\n this._handlers[path] = { def, handler: module.default };\n }\n\n /**\n * Invoke function.\n */\n public async invoke(path: string, data: any): Promise<number> {\n const seq = ++this._seq;\n const now = Date.now();\n\n log.info('req', { seq, path });\n const statusCode = await this._invoke(path, { data });\n\n log.info('res', { seq, path, statusCode, duration: Date.now() - now });\n this.update.emit(statusCode);\n return statusCode;\n }\n\n private async _invoke(path: string, event: FunctionEvent) {\n const { handler } = this._handlers[path] ?? {};\n invariant(handler, `invalid path: ${path}`);\n\n const context: FunctionContext = {\n client: this._client,\n dataDir: this._options.dataDir,\n };\n\n let statusCode = 200;\n const response: FunctionResponse = {\n status: (code: number) => {\n statusCode = code;\n return response;\n },\n };\n\n await handler({ context, event, response });\n return statusCode;\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { CronJob } from 'cron';\nimport { getPort } from 'get-port-please';\nimport http from 'node:http';\nimport path from 'node:path';\nimport WebSocket from 'ws';\n\nimport { TextV0Type } from '@braneframe/types';\nimport { debounce, DeferredTask, sleep, Trigger } from '@dxos/async';\nimport { type Client, type PublicKey } from '@dxos/client';\nimport { createSubscription, Filter, getAutomergeObjectCore, type Query, type Space } from '@dxos/client/echo';\nimport { Context } from '@dxos/context';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\nimport { ComplexMap } from '@dxos/util';\n\nimport { type FunctionEventMeta } from '../handler';\nimport { type FunctionDef, type FunctionManifest, type FunctionTrigger } from '../types';\n\nexport type Callback = (data: any) => Promise<void | number>;\n\nexport type SchedulerOptions = {\n endpoint?: string;\n callback?: Callback;\n};\n\n/**\n * The scheduler triggers function execution based on various triggers.\n */\nexport class Scheduler {\n // Map of mounted functions.\n private readonly _mounts = new ComplexMap<\n { spaceKey: PublicKey; id: string },\n { ctx: Context; trigger: FunctionTrigger }\n >(({ spaceKey, id }) => `${spaceKey.toHex()}:${id}`);\n\n constructor(\n private readonly _client: Client,\n private readonly _manifest: FunctionManifest,\n private readonly _options: SchedulerOptions = {},\n ) {}\n\n get mounts() {\n return Array.from(this._mounts.values()).reduce<FunctionTrigger[]>((acc, { trigger }) => {\n acc.push(trigger);\n return acc;\n }, []);\n }\n\n async start() {\n this._client.spaces.subscribe(async (spaces) => {\n for (const space of spaces) {\n await space.waitUntilReady();\n for (const trigger of this._manifest.triggers ?? []) {\n await this.mount(new Context(), space, trigger);\n }\n }\n });\n }\n\n async stop() {\n for (const { id, spaceKey } of this._mounts.keys()) {\n await this.unmount(id, spaceKey);\n }\n }\n\n /**\n * Mount trigger.\n */\n private async mount(ctx: Context, space: Space, trigger: FunctionTrigger) {\n const key = { spaceKey: space.key, id: trigger.function };\n const def = this._manifest.functions.find((config) => config.id === trigger.function);\n invariant(def, `Function not found: ${trigger.function}`);\n\n // TODO(burdon): Currently supports only one trigger declaration per function.\n const exists = this._mounts.get(key);\n if (!exists) {\n this._mounts.set(key, { ctx, trigger });\n log('mount', { space: space.key, trigger });\n if (ctx.disposed) {\n return;\n }\n\n //\n // Triggers types.\n //\n\n if (trigger.timer) {\n await this._createTimer(ctx, space, def, trigger);\n }\n\n if (trigger.webhook) {\n await this._createWebhook(ctx, space, def, trigger);\n }\n\n if (trigger.websocket) {\n await this._createWebsocket(ctx, space, def, trigger);\n }\n\n if (trigger.subscription) {\n await this._createSubscription(ctx, space, def, trigger);\n }\n }\n }\n\n private async unmount(id: string, spaceKey: PublicKey) {\n const key = { id, spaceKey };\n const { ctx } = this._mounts.get(key) ?? {};\n if (ctx) {\n this._mounts.delete(key);\n await ctx.dispose();\n }\n }\n\n private async _execFunction<TData, TMeta>(def: FunctionDef, trigger: FunctionTrigger, data: TData): Promise<number> {\n let status = 0;\n try {\n // TODO(burdon): Pass in Space key (common context)?\n const payload = Object.assign({}, { meta: trigger.meta as TMeta } satisfies FunctionEventMeta<TMeta>, data);\n\n const { endpoint, callback } = this._options;\n if (endpoint) {\n // TODO(burdon): Move out of scheduler (generalize as callback).\n const url = path.join(endpoint, def.path);\n log.info('exec', { function: def.id, url });\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(payload),\n });\n\n status = response.status;\n } else if (callback) {\n log.info('exec', { function: def.id });\n status = (await callback(payload)) ?? 200;\n }\n\n // Check errors.\n if (status && status >= 400) {\n throw new Error(`Response: ${status}`);\n }\n\n // const result = await response.json();\n log.info('done', { function: def.id, status });\n } catch (err: any) {\n log.error('error', { function: def.id, error: err.message });\n status = 500;\n }\n\n return status;\n }\n\n //\n // Triggers\n //\n\n /**\n * Cron timer.\n */\n private async _createTimer(ctx: Context, space: Space, def: FunctionDef, trigger: FunctionTrigger) {\n log.info('timer', { space: space.key, trigger });\n const spec = trigger.timer!;\n\n const task = new DeferredTask(ctx, async () => {\n await this._execFunction(def, trigger, { spaceKey: space.key });\n });\n\n let last = 0;\n let run = 0;\n // https://www.npmjs.com/package/cron#constructor\n const job = CronJob.from({\n cronTime: spec.cron,\n runOnInit: false,\n onTick: () => {\n // TODO(burdon): Check greater than 30s (use cron-parser).\n const now = Date.now();\n const delta = last ? now - last : 0;\n last = now;\n\n run++;\n log.info('tick', { space: space.key.truncate(), count: run, delta });\n task.schedule();\n },\n });\n\n job.start();\n ctx.onDispose(() => job.stop());\n }\n\n /**\n * Webhook.\n */\n private async _createWebhook(ctx: Context, space: Space, def: FunctionDef, trigger: FunctionTrigger) {\n log.info('webhook', { space: space.key, trigger });\n const spec = trigger.webhook!;\n\n // TODO(burdon): Enable POST hook with payload.\n const server = http.createServer(async (req, res) => {\n if (req.method !== spec.method) {\n res.statusCode = 405;\n return res.end();\n }\n\n res.statusCode = await this._execFunction(def, trigger, { spaceKey: space.key });\n res.end();\n });\n\n // TODO(burdon): Not used.\n // const DEF_PORT_RANGE = { min: 7500, max: 7599 };\n // const portRange = Object.assign({}, trigger.port, DEF_PORT_RANGE) as WebhookTrigger['port'];\n const port = await getPort({\n random: true,\n // portRange: [portRange!.min, portRange!.max],\n });\n\n // TODO(burdon): Update trigger object with actual port.\n server.listen(port, () => {\n log.info('started webhook', { port });\n spec.port = port;\n });\n\n ctx.onDispose(() => {\n server.close();\n });\n }\n\n /**\n * Websocket.\n * NOTE: The port must be unique, so the same hook cannot be used for multiple spaces.\n */\n private async _createWebsocket(\n ctx: Context,\n space: Space,\n def: FunctionDef,\n trigger: FunctionTrigger,\n options: {\n retryDelay: number;\n maxAttempts: number;\n } = {\n retryDelay: 2,\n maxAttempts: 5,\n },\n ) {\n log.info('websocket', { space: space.key, trigger });\n const spec = trigger.websocket!;\n const { url, init } = spec;\n\n let ws: WebSocket;\n for (let attempt = 1; attempt <= options.maxAttempts; attempt++) {\n const open = new Trigger<boolean>();\n\n ws = new WebSocket(url);\n Object.assign(ws, {\n onopen: () => {\n log.info('opened', { url });\n if (spec.init) {\n ws.send(new TextEncoder().encode(JSON.stringify(init)));\n }\n\n open.wake(true);\n },\n\n onclose: (event) => {\n log.info('closed', { url, code: event.code });\n // Reconnect if server closes (e.g., CF restart).\n // https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent/code\n if (event.code === 1006) {\n setTimeout(async () => {\n log.info(`reconnecting in ${options.retryDelay}s...`, { url });\n await this._createWebsocket(ctx, space, def, trigger, options);\n }, options.retryDelay * 1_000);\n }\n\n open.wake(false);\n },\n\n onerror: (event) => {\n log.catch(event.error, { url });\n },\n\n onmessage: async (event) => {\n try {\n const data = JSON.parse(new TextDecoder().decode(event.data as Uint8Array));\n await this._execFunction(def, trigger, { spaceKey: space.key, data });\n } catch (err) {\n log.catch(err, { url });\n }\n },\n } satisfies Partial<WebSocket>);\n\n const isOpen = await open.wait();\n if (isOpen) {\n break;\n } else {\n const wait = Math.pow(attempt, 2) * options.retryDelay;\n if (attempt < options.maxAttempts) {\n log.warn(`failed to connect; trying again in ${wait}s`, { attempt });\n await sleep(wait * 1_000);\n }\n }\n }\n\n ctx.onDispose(() => {\n ws?.close();\n });\n }\n\n /**\n * ECHO subscription.\n */\n private async _createSubscription(ctx: Context, space: Space, def: FunctionDef, trigger: FunctionTrigger) {\n log.info('subscription', { space: space.key, trigger });\n const spec = trigger.subscription!;\n\n const objectIds = new Set<string>();\n const task = new DeferredTask(ctx, async () => {\n await this._execFunction(def, trigger, { spaceKey: space.key, objects: Array.from(objectIds) });\n });\n\n // TODO(burdon): Don't fire initially?\n // TODO(burdon): Create queue. Only allow one invocation per trigger at a time?\n const subscriptions: (() => void)[] = [];\n const subscription = createSubscription(({ added, updated }) => {\n log.info('updated', { added: added.length, updated: updated.length });\n for (const object of added) {\n objectIds.add(object.id);\n }\n for (const object of updated) {\n objectIds.add(object.id);\n }\n\n task.schedule();\n });\n\n subscriptions.push(() => subscription.unsubscribe());\n\n // TODO(burdon): Disable trigger if keeps failing.\n const { filter, options: { deep, delay } = {} } = spec;\n const update = ({ objects }: Query) => {\n subscription.update(objects);\n\n // TODO(burdon): Hack to monitor changes to Document's text object.\n if (deep) {\n log.info('update', { objects: objects.length });\n for (const object of objects) {\n const content = object.content;\n if (content instanceof TextV0Type) {\n subscriptions.push(\n getAutomergeObjectCore(content).updates.on(debounce(() => subscription.update([object]), 1_000)),\n );\n }\n }\n }\n };\n\n // TODO(burdon): Is Filter.or implemented?\n // TODO(burdon): [Bug]: all callbacks are fired on the first mutation.\n // TODO(burdon): [Bug]: not updated when document is deleted (either top or hierarchically).\n const query = space.db.query(Filter.or(filter.map(({ type, props }) => Filter.typename(type, props))));\n subscriptions.push(query.subscribe(delay ? debounce(update, delay) : update));\n\n ctx.onDispose(() => {\n subscriptions.forEach((unsubscribe) => unsubscribe());\n });\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport * as S from '@effect/schema/Schema';\n\nconst TimerTriggerSchema = S.struct({\n cron: S.string,\n});\n\nconst WebhookTriggerSchema = S.mutable(\n S.struct({\n method: S.string,\n // Assigned port.\n port: S.optional(S.number),\n }),\n);\n\nconst WebsocketTriggerSchema = S.struct({\n url: S.string,\n init: S.optional(S.record(S.string, S.any)),\n});\n\nconst SubscriptionTriggerSchema = S.struct({\n spaceKey: S.optional(S.string),\n // TODO(burdon): Define query DSL.\n filter: S.array(\n S.struct({\n type: S.string,\n props: S.optional(S.record(S.string, S.any)),\n }),\n ),\n options: S.optional(\n S.struct({\n // Watch changes to object (not just creation).\n deep: S.optional(S.boolean),\n // Debounce changes (delay in ms).\n delay: S.optional(S.number),\n }),\n ),\n});\n\nconst FunctionTriggerSchema = S.struct({\n function: S.string.pipe(S.description('Function ID/URI.')),\n\n // Context passed to function.\n meta: S.optional(S.record(S.string, S.any)),\n\n // Triggers.\n timer: S.optional(TimerTriggerSchema),\n webhook: S.optional(WebhookTriggerSchema),\n websocket: S.optional(WebsocketTriggerSchema),\n subscription: S.optional(SubscriptionTriggerSchema),\n});\n\nexport type FunctionTrigger = S.Schema.Type<typeof FunctionTriggerSchema>;\n\nexport type TimerTrigger = S.Schema.Type<typeof TimerTriggerSchema>;\nexport type WebhookTrigger = S.Schema.Type<typeof WebhookTriggerSchema>;\nexport type WebsocketTrigger = S.Schema.Type<typeof WebsocketTriggerSchema>;\nexport type SubscriptionTrigger = S.Schema.Type<typeof SubscriptionTriggerSchema>;\n\n/**\n * Function definition.\n */\n// TODO(burdon): Name vs. path?\nconst FunctionDefSchema = S.struct({\n id: S.string,\n // name: S.string,\n description: S.optional(S.string),\n // TODO(burdon): Rename route?\n path: S.string,\n // TODO(burdon): NPM/GitHub/Docker/CF URL?\n handler: S.string,\n});\n\nexport type FunctionDef = S.Schema.Type<typeof FunctionDefSchema>;\n\n/**\n * Function manifest file.\n */\nexport const FunctionManifestSchema = S.struct({\n functions: S.mutable(S.array(FunctionDefSchema)),\n triggers: S.optional(S.mutable(S.array(FunctionTriggerSchema))),\n});\n\nexport type FunctionManifest = S.Schema.Type<typeof FunctionManifestSchema>;\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["PublicKey", "log", "nonNullable", "subscriptionHandler", "handler", "event", "data", "context", "rest", "client", "space", "spaceKey", "spaces", "get", "from", "undefined", "objects", "map", "id", "db", "getObjectById", "filter", "warn", "info", "key", "truncate", "length", "express", "getPort", "join", "Event", "Trigger", "invariant", "log", "DevServer", "constructor", "_client", "_options", "_handlers", "_seq", "update", "Event", "stats", "seq", "endpoint", "invariant", "_port", "proxy", "_proxy", "functions", "Object", "values", "initialize", "def", "manifest", "_load", "err", "log", "error", "start", "_server", "info", "app", "express", "use", "json", "post", "req", "res", "path", "params", "reload", "statusCode", "invoke", "body", "end", "catch", "getPort", "host", "port", "portRange", "listen", "registrationId", "services", "FunctionRegistryService", "register", "map", "id", "_functionServiceRegistration", "stop", "Error", "trigger", "Trigger", "close", "unregister", "undefined", "wake", "throw", "wait", "force", "handler", "filePath", "join", "baseDir", "keys", "require", "cache", "filter", "key", "startsWith", "forEach", "module", "default", "data", "now", "Date", "_invoke", "duration", "emit", "event", "context", "client", "dataDir", "response", "status", "code", "CronJob", "getPort", "http", "path", "WebSocket", "TextV0Type", "debounce", "DeferredTask", "sleep", "Trigger", "createSubscription", "Filter", "getAutomergeObjectCore", "Context", "invariant", "log", "ComplexMap", "Scheduler", "constructor", "_client", "_manifest", "_options", "_mounts", "spaceKey", "id", "toHex", "mounts", "Array", "from", "values", "reduce", "acc", "trigger", "push", "start", "spaces", "subscribe", "space", "waitUntilReady", "triggers", "mount", "stop", "keys", "unmount", "ctx", "key", "function", "def", "functions", "find", "config", "exists", "get", "set", "disposed", "timer", "_createTimer", "webhook", "_createWebhook", "websocket", "_createWebsocket", "subscription", "_createSubscription", "delete", "dispose", "_execFunction", "data", "status", "payload", "Object", "assign", "meta", "endpoint", "callback", "url", "join", "info", "response", "fetch", "method", "headers", "body", "JSON", "stringify", "Error", "err", "error", "message", "spec", "task", "last", "run", "job", "cronTime", "cron", "runOnInit", "onTick", "now", "Date", "delta", "truncate", "count", "schedule", "onDispose", "server", "createServer", "req", "res", "statusCode", "end", "port", "random", "listen", "close", "options", "retryDelay", "maxAttempts", "init", "ws", "attempt", "open", "onopen", "send", "TextEncoder", "encode", "wake", "onclose", "event", "code", "setTimeout", "onerror", "catch", "onmessage", "parse", "TextDecoder", "decode", "isOpen", "wait", "Math", "pow", "warn", "objectIds", "Set", "objects", "subscriptions", "added", "updated", "length", "object", "add", "unsubscribe", "filter", "deep", "delay", "update", "content", "updates", "on", "query", "db", "or", "map", "type", "props", "typename", "forEach", "S", "TimerTriggerSchema", "struct", "cron", "string", "WebhookTriggerSchema", "mutable", "method", "port", "optional", "number", "WebsocketTriggerSchema", "url", "init", "record", "any", "SubscriptionTriggerSchema", "spaceKey", "filter", "array", "type", "props", "options", "deep", "boolean", "delay", "FunctionTriggerSchema", "function", "pipe", "description", "meta", "timer", "webhook", "websocket", "subscription", "FunctionDefSchema", "id", "path", "handler", "FunctionManifestSchema", "functions", "triggers"]
|
|
7
7
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"inputs":{"inject-globals:@inject-globals":{"bytes":384,"imports":[{"path":"@dxos/node-std/inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/core/functions/src/handler.ts":{"bytes":
|
|
1
|
+
{"inputs":{"inject-globals:@inject-globals":{"bytes":384,"imports":[{"path":"@dxos/node-std/inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/core/functions/src/handler.ts":{"bytes":6874,"imports":[{"path":"@dxos/client","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/core/functions/src/runtime/dev-server.ts":{"bytes":24379,"imports":[{"path":"express","kind":"import-statement","external":true},{"path":"get-port-please","kind":"import-statement","external":true},{"path":"@dxos/node-std/path","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@inject-globals","kind":"import-statement","external":true},{"path":"<runtime>","kind":"import-statement","external":true}],"format":"esm"},"packages/core/functions/src/runtime/scheduler.ts":{"bytes":44375,"imports":[{"path":"cron","kind":"import-statement","external":true},{"path":"get-port-please","kind":"import-statement","external":true},{"path":"@dxos/node-std/http","kind":"import-statement","external":true},{"path":"@dxos/node-std/path","kind":"import-statement","external":true},{"path":"ws","kind":"import-statement","external":true},{"path":"@braneframe/types","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/client/echo","kind":"import-statement","external":true},{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/core/functions/src/runtime/index.ts":{"bytes":566,"imports":[{"path":"packages/core/functions/src/runtime/dev-server.ts","kind":"import-statement","original":"./dev-server"},{"path":"packages/core/functions/src/runtime/scheduler.ts","kind":"import-statement","original":"./scheduler"},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/core/functions/src/types.ts":{"bytes":7861,"imports":[{"path":"@effect/schema/Schema","kind":"import-statement","external":true},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/core/functions/src/index.ts":{"bytes":630,"imports":[{"path":"packages/core/functions/src/handler.ts","kind":"import-statement","original":"./handler"},{"path":"packages/core/functions/src/runtime/index.ts","kind":"import-statement","original":"./runtime"},{"path":"packages/core/functions/src/types.ts","kind":"import-statement","original":"./types"},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"}},"outputs":{"packages/core/functions/dist/lib/browser/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":38894},"packages/core/functions/dist/lib/browser/index.mjs":{"imports":[{"path":"@dxos/node-std/inject-globals","kind":"import-statement","external":true},{"path":"@dxos/client","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"express","kind":"import-statement","external":true},{"path":"get-port-please","kind":"import-statement","external":true},{"path":"@dxos/node-std/path","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"cron","kind":"import-statement","external":true},{"path":"get-port-please","kind":"import-statement","external":true},{"path":"@dxos/node-std/http","kind":"import-statement","external":true},{"path":"@dxos/node-std/path","kind":"import-statement","external":true},{"path":"ws","kind":"import-statement","external":true},{"path":"@braneframe/types","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/client/echo","kind":"import-statement","external":true},{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"@effect/schema/Schema","kind":"import-statement","external":true}],"exports":["DevServer","FunctionManifestSchema","Scheduler","subscriptionHandler"],"entryPoint":"packages/core/functions/src/index.ts","inputs":{"inject-globals:@inject-globals":{"bytesInOutput":90},"packages/core/functions/src/handler.ts":{"bytesInOutput":1124},"packages/core/functions/src/index.ts":{"bytesInOutput":0},"packages/core/functions/src/runtime/dev-server.ts":{"bytesInOutput":6965},"packages/core/functions/src/runtime/index.ts":{"bytesInOutput":0},"packages/core/functions/src/runtime/scheduler.ts":{"bytesInOutput":11382},"packages/core/functions/src/types.ts":{"bytesInOutput":1528}},"bytes":21838}}}
|