@dxos/functions 0.5.3-main.ce64a40 → 0.5.3-main.d7fe7b5
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 +2 -2
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node/index.cjs +2 -2
- package/dist/lib/node/index.cjs.map +3 -3
- package/dist/lib/node/meta.json +1 -1
- package/package.json +14 -14
- package/src/registry/function-registry.ts +1 -1
- package/src/trigger/trigger-registry.ts +1 -1
|
@@ -146,7 +146,7 @@ var FunctionRegistry = class extends Resource {
|
|
|
146
146
|
if (!manifest.functions?.length) {
|
|
147
147
|
return;
|
|
148
148
|
}
|
|
149
|
-
if (!space.db.graph.runtimeSchemaRegistry.
|
|
149
|
+
if (!space.db.graph.runtimeSchemaRegistry.isSchemaRegistered(FunctionDef)) {
|
|
150
150
|
space.db.graph.runtimeSchemaRegistry.registerSchema(FunctionDef);
|
|
151
151
|
}
|
|
152
152
|
const { objects: existingDefinitions } = await space.db.query(Filter.schema(FunctionDef)).run();
|
|
@@ -982,7 +982,7 @@ var TriggerRegistry = class extends Resource2 {
|
|
|
982
982
|
if (!manifest.triggers?.length) {
|
|
983
983
|
return;
|
|
984
984
|
}
|
|
985
|
-
if (!space.db.graph.runtimeSchemaRegistry.
|
|
985
|
+
if (!space.db.graph.runtimeSchemaRegistry.isSchemaRegistered(FunctionTrigger)) {
|
|
986
986
|
space.db.graph.runtimeSchemaRegistry.registerSchema(FunctionTrigger);
|
|
987
987
|
}
|
|
988
988
|
const reactiveObjects = manifest.triggers.map((template) => create2(FunctionTrigger, {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/handler.ts", "../../../src/registry/function-registry.ts", "../../../src/types.ts", "../../../src/runtime/dev-server.ts", "../../../src/runtime/scheduler.ts", "../../../src/trigger/trigger-registry.ts", "../../../src/trigger/type/subscription-trigger.ts", "../../../src/trigger/type/timer-trigger.ts", "../../../src/trigger/type/webhook-trigger.ts", "../../../src/trigger/type/websocket-trigger.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 2024 DXOS.org\n//\n\nimport { Event } from '@dxos/async';\nimport { type Client } from '@dxos/client';\nimport { create, Filter, type Space } from '@dxos/client/echo';\nimport { type Context, Resource } from '@dxos/context';\nimport { PublicKey } from '@dxos/keys';\nimport { ComplexMap } from '@dxos/util';\n\nimport { FunctionDef, type FunctionManifest } from '../types';\n\nexport type FunctionsRegisteredEvent = {\n space: Space;\n newFunctions: FunctionDef[];\n};\n\nexport class FunctionRegistry extends Resource {\n private readonly _functionBySpaceKey = new ComplexMap<PublicKey, FunctionDef[]>(PublicKey.hash);\n\n public readonly onFunctionsRegistered = new Event<FunctionsRegisteredEvent>();\n\n constructor(private readonly _client: Client) {\n super();\n }\n\n public getFunctions(space: Space): FunctionDef[] {\n return this._functionBySpaceKey.get(space.key) ?? [];\n }\n\n /**\n * The method loads function definitions from the manifest into the space.\n * We first load all the definitions from the space to deduplicate by functionId.\n */\n // TODO(burdon): This should not be space specific (they are static for the agent).\n public async register(space: Space, manifest: FunctionManifest): Promise<void> {\n if (!manifest.functions?.length) {\n return;\n }\n if (!space.db.graph.runtimeSchemaRegistry.hasSchema(FunctionDef)) {\n space.db.graph.runtimeSchemaRegistry.registerSchema(FunctionDef);\n }\n\n const { objects: existingDefinitions } = await space.db.query(Filter.schema(FunctionDef)).run();\n const newDefinitions = getNewDefinitions(manifest.functions, existingDefinitions);\n const reactiveObjects = newDefinitions.map((template) => create(FunctionDef, { ...template }));\n reactiveObjects.forEach((obj) => space.db.add(obj));\n }\n\n protected override async _open(): Promise<void> {\n const spaceListSubscription = this._client.spaces.subscribe(async (spaces) => {\n for (const space of spaces) {\n if (this._functionBySpaceKey.has(space.key)) {\n continue;\n }\n const registered: FunctionDef[] = [];\n this._functionBySpaceKey.set(space.key, registered);\n await space.waitUntilReady();\n if (this._ctx.disposed) {\n break;\n }\n\n const functionsSubscription = space.db.query(Filter.schema(FunctionDef)).subscribe((definitions) => {\n const newFunctions = getNewDefinitions(definitions.objects, registered);\n if (newFunctions.length > 0) {\n registered.push(...newFunctions);\n this.onFunctionsRegistered.emit({ space, newFunctions });\n }\n });\n this._ctx.onDispose(functionsSubscription);\n }\n });\n this._ctx.onDispose(() => spaceListSubscription.unsubscribe());\n }\n\n protected override async _close(_: Context): Promise<void> {\n this._functionBySpaceKey.clear();\n }\n}\n\nconst getNewDefinitions = <T extends { uri: string }>(candidateList: T[], existing: FunctionDef[]): T[] => {\n return candidateList.filter((candidate) => existing.find((def) => def.uri === candidate.uri) == null);\n};\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { AST, S, TypedObject } from '@dxos/echo-schema';\n\n// TODO(burdon): Factor out.\nconst omitEchoId = <T>(schema: S.Schema<T>): S.Schema<Omit<T, 'id'>> => S.make(AST.omit(schema.ast, ['id']));\n\n/**\n * Type discriminator for TriggerSpec.\n * Every spec has a type field of type FunctionTriggerType that we can use to understand which\n * type we're working with.\n * https://www.typescriptlang.org/docs/handbook/2/narrowing.html#discriminated-unions\n */\nexport type FunctionTriggerType = 'subscription' | 'timer' | 'webhook' | 'websocket';\n\nconst SubscriptionTriggerSchema = S.struct({\n type: S.literal('subscription'),\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});\nexport type SubscriptionTrigger = S.Schema.Type<typeof SubscriptionTriggerSchema>;\n\nconst TimerTriggerSchema = S.struct({\n type: S.literal('timer'),\n cron: S.string,\n});\nexport type TimerTrigger = S.Schema.Type<typeof TimerTriggerSchema>;\n\nconst WebhookTriggerSchema = S.mutable(\n S.struct({\n type: S.literal('webhook'),\n method: S.string,\n // Assigned port.\n port: S.optional(S.number),\n }),\n);\nexport type WebhookTrigger = S.Schema.Type<typeof WebhookTriggerSchema>;\n\nconst WebsocketTriggerSchema = S.struct({\n type: S.literal('websocket'),\n url: S.string,\n init: S.optional(S.record(S.string, S.any)),\n});\nexport type WebsocketTrigger = S.Schema.Type<typeof WebsocketTriggerSchema>;\n\nconst TriggerSpecSchema = S.union(\n TimerTriggerSchema,\n WebhookTriggerSchema,\n WebsocketTriggerSchema,\n SubscriptionTriggerSchema,\n);\nexport type TriggerSpec = TimerTrigger | WebhookTrigger | WebsocketTrigger | SubscriptionTrigger;\n\n/**\n * Function definition.\n */\nexport class FunctionDef extends TypedObject({\n typename: 'dxos.org/type/FunctionDef',\n version: '0.1.0',\n})({\n uri: S.string,\n description: S.optional(S.string),\n route: S.string,\n // TODO(burdon): NPM/GitHub/Docker/CF URL?\n handler: S.string,\n}) {}\n\nexport class FunctionTrigger extends TypedObject({\n typename: 'dxos.org/type/FunctionTrigger',\n version: '0.1.0',\n})({\n function: S.string.pipe(S.description('Function ID/URI.')),\n // Context passed to a function.\n meta: S.optional(S.record(S.string, S.any)),\n spec: TriggerSpecSchema,\n}) {}\n\n/**\n * Function manifest file.\n */\nexport const FunctionManifestSchema = S.struct({\n functions: S.optional(S.mutable(S.array(omitEchoId(FunctionDef)))),\n triggers: S.optional(S.mutable(S.array(omitEchoId(FunctionTrigger)))),\n});\n\nexport type FunctionManifest = S.Schema.Type<typeof FunctionManifestSchema>;\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 { Context } from '@dxos/context';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\n\nimport { type FunctionContext, type FunctionEvent, type FunctionHandler, type FunctionResponse } from '../handler';\nimport { type FunctionRegistry } from '../registry';\nimport { type FunctionDef } from '../types';\n\nexport type DevServerOptions = {\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 private _ctx = createContext();\n\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 _functionsRegistry: FunctionRegistry,\n private readonly _options: DevServerOptions,\n ) {\n this._functionsRegistry.onFunctionsRegistered.on(async ({ newFunctions }) => {\n newFunctions.forEach((def) => this._load(def));\n await this._safeUpdateRegistration();\n log('new functions loaded', { newFunctions });\n });\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 start() {\n invariant(!this._server);\n log.info('starting...');\n this._ctx = createContext();\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 });\n\n log.info('registered', { endpoint });\n this._proxy = endpoint;\n this._functionServiceRegistration = registrationId;\n\n // Open after registration, so that it can be updated with the list of function definitions.\n await this._functionsRegistry.open(this._ctx);\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 { uri, route, handler } = def;\n const filePath = join(this._options.baseDir, handler);\n log.info('loading', { uri, 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 // TODO(burdon): Import types.\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: ${uri}`);\n }\n\n this._handlers[route] = { def, handler: module.default };\n }\n\n private async _safeUpdateRegistration(): Promise<void> {\n invariant(this._functionServiceRegistration);\n try {\n await this._client.services.services.FunctionRegistryService!.updateRegistration({\n registrationId: this._functionServiceRegistration,\n functions: this.functions.map(({ def: { id, route } }) => ({ id, route })),\n });\n } catch (e) {\n log.catch(e);\n }\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\nconst createContext = () => new Context({ name: 'DevServer' });\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport path from 'node:path';\n\nimport { type Space } from '@dxos/client/echo';\nimport { Context } from '@dxos/context';\nimport { log } from '@dxos/log';\n\nimport { type FunctionEventMeta } from '../handler';\nimport { type FunctionRegistry } from '../registry';\nimport { type TriggerRegistry } from '../trigger';\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 private _ctx = createContext();\n\n constructor(\n public readonly functions: FunctionRegistry,\n public readonly triggers: TriggerRegistry,\n private readonly _options: SchedulerOptions = {},\n ) {\n this.functions.onFunctionsRegistered.on(async ({ space, newFunctions }) => {\n await this._safeActivateTriggers(space, this.triggers.getInactiveTriggers(space), newFunctions);\n });\n this.triggers.registered.on(async ({ space, triggers }) => {\n await this._safeActivateTriggers(space, triggers, this.functions.getFunctions(space));\n });\n }\n\n async start() {\n await this._ctx.dispose();\n this._ctx = createContext();\n await this.functions.open(this._ctx);\n await this.triggers.open(this._ctx);\n }\n\n async stop() {\n await this._ctx.dispose();\n await this.functions.close();\n await this.triggers.close();\n }\n\n public async register(space: Space, manifest: FunctionManifest) {\n await this.functions.register(space, manifest);\n await this.triggers.register(space, manifest);\n }\n\n private async _safeActivateTriggers(\n space: Space,\n triggers: FunctionTrigger[],\n functions: FunctionDef[],\n ): Promise<void> {\n const mountTasks = triggers.map((trigger) => {\n return this.activate(space, functions, trigger);\n });\n await Promise.all(mountTasks).catch(log.catch);\n }\n\n private async activate(space: Space, functions: FunctionDef[], fnTrigger: FunctionTrigger) {\n const definition = functions.find((def) => def.uri === fnTrigger.function);\n if (!definition) {\n log.info('function is not found for trigger', { fnTrigger });\n return;\n }\n\n await this.triggers.activate({ space }, fnTrigger, async (args) => {\n return this._execFunction(definition, {\n meta: fnTrigger.meta,\n data: { ...args, spaceKey: space.key },\n });\n });\n log('activated trigger', { space: space.key, trigger: fnTrigger });\n }\n\n private async _execFunction<TData, TMeta>(\n def: FunctionDef,\n { data, meta }: { data: TData; meta?: TMeta },\n ): Promise<number> {\n let status = 0;\n try {\n // TODO(burdon): Pass in Space key (common context)?\n const payload = Object.assign({}, meta && ({ meta } 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.route);\n log.info('exec', { function: def.uri, 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.uri });\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.uri, status });\n } catch (err: any) {\n log.error('error', { function: def.uri, error: err.message });\n status = 500;\n }\n\n return status;\n }\n}\n\nconst createContext = () => new Context({ name: 'FunctionScheduler' });\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { Event } from '@dxos/async';\nimport { type Client } from '@dxos/client';\nimport { create, Filter, type Space } from '@dxos/client/echo';\nimport { Context, Resource } from '@dxos/context';\nimport { invariant } from '@dxos/invariant';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { ComplexMap } from '@dxos/util';\n\nimport { createSubscriptionTrigger, createTimerTrigger, createWebhookTrigger, createWebsocketTrigger } from './type';\nimport { type FunctionManifest, FunctionTrigger, type FunctionTriggerType, type TriggerSpec } from '../types';\n\ntype ResponseCode = number;\n\nexport type TriggerCallback = (args: object) => Promise<ResponseCode>;\n\nexport type TriggerContext = { space: Space };\n\n// TODO(burdon): Make object?\nexport type TriggerFactory<Spec extends TriggerSpec, Options = any> = (\n ctx: Context,\n context: TriggerContext,\n spec: Spec,\n callback: TriggerCallback,\n options?: Options,\n) => Promise<void>;\n\nexport type TriggerHandlerMap = { [type in FunctionTriggerType]: TriggerFactory<any> };\n\nconst triggerHandlers: TriggerHandlerMap = {\n subscription: createSubscriptionTrigger,\n timer: createTimerTrigger,\n webhook: createWebhookTrigger,\n websocket: createWebsocketTrigger,\n};\n\nexport type TriggerEvent = {\n space: Space;\n triggers: FunctionTrigger[];\n};\n\ntype RegisteredTrigger = {\n activationCtx?: Context;\n trigger: FunctionTrigger;\n};\n\nexport class TriggerRegistry extends Resource {\n private readonly _triggersBySpaceKey = new ComplexMap<PublicKey, RegisteredTrigger[]>(PublicKey.hash);\n\n public readonly registered = new Event<TriggerEvent>();\n public readonly removed = new Event<TriggerEvent>();\n\n constructor(\n private readonly _client: Client,\n private readonly _options?: TriggerHandlerMap,\n ) {\n super();\n }\n\n public getActiveTriggers(space: Space): FunctionTrigger[] {\n return this._getTriggers(space, (t) => t.activationCtx != null);\n }\n\n public getInactiveTriggers(space: Space): FunctionTrigger[] {\n return this._getTriggers(space, (t) => t.activationCtx == null);\n }\n\n async activate(triggerCtx: TriggerContext, trigger: FunctionTrigger, callback: TriggerCallback): Promise<void> {\n log('activate', { space: triggerCtx.space.key, trigger });\n const activationCtx = new Context({ name: `trigger_${trigger.function}` });\n this._ctx.onDispose(() => activationCtx.dispose());\n const registeredTrigger = this._triggersBySpaceKey\n .get(triggerCtx.space.key)\n ?.find((reg) => reg.trigger.id === trigger.id);\n invariant(registeredTrigger, `Trigger is not registered: ${trigger.function}`);\n registeredTrigger.activationCtx = activationCtx;\n\n try {\n const options = this._options?.[trigger.spec.type];\n await triggerHandlers[trigger.spec.type](activationCtx, triggerCtx, trigger.spec, callback, options);\n } catch (err) {\n delete registeredTrigger.activationCtx;\n throw err;\n }\n }\n\n /**\n * Loads triggers from the manifest into the space.\n */\n public async register(space: Space, manifest: FunctionManifest): Promise<void> {\n log('register', { space: space.key });\n if (!manifest.triggers?.length) {\n return;\n }\n if (!space.db.graph.runtimeSchemaRegistry.hasSchema(FunctionTrigger)) {\n space.db.graph.runtimeSchemaRegistry.registerSchema(FunctionTrigger);\n }\n\n const reactiveObjects = manifest.triggers.map((template: Omit<FunctionTrigger, 'id'>) =>\n create(FunctionTrigger, { ...template }),\n );\n reactiveObjects.forEach((obj) => space.db.add(obj));\n }\n\n protected override async _open(): Promise<void> {\n const spaceListSubscription = this._client.spaces.subscribe(async (spaces) => {\n for (const space of spaces) {\n if (this._triggersBySpaceKey.has(space.key)) {\n continue;\n }\n\n const registered: RegisteredTrigger[] = [];\n this._triggersBySpaceKey.set(space.key, registered);\n await space.waitUntilReady();\n if (this._ctx.disposed) {\n break;\n }\n const functionsSubscription = space.db.query(Filter.schema(FunctionTrigger)).subscribe(async (triggers) => {\n await this._handleRemovedTriggers(space, triggers.objects, registered);\n this._handleNewTriggers(space, triggers.objects, registered);\n });\n\n this._ctx.onDispose(functionsSubscription);\n }\n });\n\n this._ctx.onDispose(() => spaceListSubscription.unsubscribe());\n }\n\n protected override async _close(_: Context): Promise<void> {\n this._triggersBySpaceKey.clear();\n }\n\n private _handleNewTriggers(space: Space, allTriggers: FunctionTrigger[], registered: RegisteredTrigger[]) {\n const newTriggers = allTriggers.filter((candidate) => {\n return registered.find((reg) => reg.trigger.id === candidate.id) == null;\n });\n\n if (newTriggers.length > 0) {\n const newRegisteredTriggers: RegisteredTrigger[] = newTriggers.map((trigger) => ({ trigger }));\n registered.push(...newRegisteredTriggers);\n log('registered new triggers', () => ({ spaceKey: space.key, functions: newTriggers.map((t) => t.function) }));\n this.registered.emit({ space, triggers: newTriggers });\n }\n }\n\n private async _handleRemovedTriggers(\n space: Space,\n allTriggers: FunctionTrigger[],\n registered: RegisteredTrigger[],\n ): Promise<void> {\n const removed: FunctionTrigger[] = [];\n for (let i = registered.length - 1; i >= 0; i--) {\n const wasRemoved =\n allTriggers.find((trigger: FunctionTrigger) => trigger.id === registered[i].trigger.id) == null;\n if (wasRemoved) {\n const unregistered = registered.splice(i, 1)[0];\n await unregistered.activationCtx?.dispose();\n removed.push(unregistered.trigger);\n }\n }\n\n if (removed.length > 0) {\n this.removed.emit({ space, triggers: removed });\n }\n }\n\n private _getTriggers(space: Space, predicate: (trigger: RegisteredTrigger) => boolean): FunctionTrigger[] {\n const allSpaceTriggers = this._triggersBySpaceKey.get(space.key) ?? [];\n return allSpaceTriggers.filter(predicate).map((trigger) => trigger.trigger);\n }\n}\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { TextV0Type } from '@braneframe/types';\nimport { debounce, DeferredTask } from '@dxos/async';\nimport { type Context } from '@dxos/context';\nimport { createSubscription, Filter, getAutomergeObjectCore, type Query } from '@dxos/echo-db';\nimport { log } from '@dxos/log';\n\nimport type { SubscriptionTrigger } from '../../types';\nimport { type TriggerCallback, type TriggerContext, type TriggerFactory } from '../trigger-registry';\n\nexport const createSubscriptionTrigger: TriggerFactory<SubscriptionTrigger> = async (\n ctx: Context,\n triggerCtx: TriggerContext,\n spec: SubscriptionTrigger,\n callback: TriggerCallback,\n) => {\n const objectIds = new Set<string>();\n const task = new DeferredTask(ctx, async () => {\n if (objectIds.size > 0) {\n await callback({ objects: Array.from(objectIds) });\n objectIds.clear();\n }\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 = triggerCtx.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// Copyright 2024 DXOS.org\n//\n\nimport { CronJob } from 'cron';\n\nimport { DeferredTask } from '@dxos/async';\nimport { type Context } from '@dxos/context';\nimport { log } from '@dxos/log';\n\nimport type { TimerTrigger } from '../../types';\nimport { type TriggerCallback, type TriggerContext, type TriggerFactory } from '../trigger-registry';\n\nexport const createTimerTrigger: TriggerFactory<TimerTrigger> = async (\n ctx: Context,\n triggerContext: TriggerContext,\n spec: TimerTrigger,\n callback: TriggerCallback,\n) => {\n const task = new DeferredTask(ctx, async () => {\n await callback({});\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: triggerContext.space.key.truncate(), count: run, delta });\n task.schedule();\n },\n });\n\n job.start();\n ctx.onDispose(() => job.stop());\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { getPort } from 'get-port-please';\nimport http from 'node:http';\n\nimport { type Context } from '@dxos/context';\nimport { log } from '@dxos/log';\n\nimport type { WebhookTrigger } from '../../types';\nimport { type TriggerCallback, type TriggerContext, type TriggerFactory } from '../trigger-registry';\n\nexport const createWebhookTrigger: TriggerFactory<WebhookTrigger> = async (\n ctx: Context,\n _: TriggerContext,\n spec: WebhookTrigger,\n callback: TriggerCallback,\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 res.statusCode = await callback({});\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// Copyright 2024 DXOS.org\n//\n\nimport WebSocket from 'ws';\n\nimport { sleep, Trigger } from '@dxos/async';\nimport { type Context } from '@dxos/context';\nimport { log } from '@dxos/log';\n\nimport { type WebsocketTrigger } from '../../types';\nimport { type TriggerCallback, type TriggerContext, type TriggerFactory } from '../trigger-registry';\n\ninterface WebsocketTriggerOptions {\n retryDelay: number;\n maxAttempts: number;\n}\n\n/**\n * Websocket.\n * NOTE: The port must be unique, so the same hook cannot be used for multiple spaces.\n */\nexport const createWebsocketTrigger: TriggerFactory<WebsocketTrigger, WebsocketTriggerOptions> = async (\n ctx: Context,\n triggerCtx: TriggerContext,\n spec: WebsocketTrigger,\n callback: TriggerCallback,\n options: WebsocketTriggerOptions = { retryDelay: 2, maxAttempts: 5 },\n) => {\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 createWebsocketTrigger(ctx, triggerCtx, spec, callback, 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 log.info('message');\n const data = JSON.parse(new TextDecoder().decode(event.data as Uint8Array));\n await callback({ 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"],
|
|
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", "Event", "create", "Filter", "Resource", "PublicKey", "ComplexMap", "AST", "S", "TypedObject", "omitEchoId", "schema", "S", "make", "AST", "omit", "ast", "SubscriptionTriggerSchema", "struct", "type", "literal", "filter", "array", "string", "props", "optional", "record", "any", "options", "deep", "boolean", "delay", "number", "TimerTriggerSchema", "cron", "WebhookTriggerSchema", "mutable", "method", "port", "WebsocketTriggerSchema", "url", "init", "TriggerSpecSchema", "union", "FunctionDef", "TypedObject", "typename", "version", "uri", "description", "route", "handler", "FunctionTrigger", "function", "pipe", "meta", "spec", "FunctionManifestSchema", "functions", "triggers", "FunctionRegistry", "Resource", "constructor", "_client", "_functionBySpaceKey", "ComplexMap", "PublicKey", "hash", "onFunctionsRegistered", "Event", "getFunctions", "space", "get", "key", "register", "manifest", "functions", "length", "db", "graph", "runtimeSchemaRegistry", "
|
|
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 2024 DXOS.org\n//\n\nimport { Event } from '@dxos/async';\nimport { type Client } from '@dxos/client';\nimport { create, Filter, type Space } from '@dxos/client/echo';\nimport { type Context, Resource } from '@dxos/context';\nimport { PublicKey } from '@dxos/keys';\nimport { ComplexMap } from '@dxos/util';\n\nimport { FunctionDef, type FunctionManifest } from '../types';\n\nexport type FunctionsRegisteredEvent = {\n space: Space;\n newFunctions: FunctionDef[];\n};\n\nexport class FunctionRegistry extends Resource {\n private readonly _functionBySpaceKey = new ComplexMap<PublicKey, FunctionDef[]>(PublicKey.hash);\n\n public readonly onFunctionsRegistered = new Event<FunctionsRegisteredEvent>();\n\n constructor(private readonly _client: Client) {\n super();\n }\n\n public getFunctions(space: Space): FunctionDef[] {\n return this._functionBySpaceKey.get(space.key) ?? [];\n }\n\n /**\n * The method loads function definitions from the manifest into the space.\n * We first load all the definitions from the space to deduplicate by functionId.\n */\n // TODO(burdon): This should not be space specific (they are static for the agent).\n public async register(space: Space, manifest: FunctionManifest): Promise<void> {\n if (!manifest.functions?.length) {\n return;\n }\n if (!space.db.graph.runtimeSchemaRegistry.isSchemaRegistered(FunctionDef)) {\n space.db.graph.runtimeSchemaRegistry.registerSchema(FunctionDef);\n }\n\n const { objects: existingDefinitions } = await space.db.query(Filter.schema(FunctionDef)).run();\n const newDefinitions = getNewDefinitions(manifest.functions, existingDefinitions);\n const reactiveObjects = newDefinitions.map((template) => create(FunctionDef, { ...template }));\n reactiveObjects.forEach((obj) => space.db.add(obj));\n }\n\n protected override async _open(): Promise<void> {\n const spaceListSubscription = this._client.spaces.subscribe(async (spaces) => {\n for (const space of spaces) {\n if (this._functionBySpaceKey.has(space.key)) {\n continue;\n }\n const registered: FunctionDef[] = [];\n this._functionBySpaceKey.set(space.key, registered);\n await space.waitUntilReady();\n if (this._ctx.disposed) {\n break;\n }\n\n const functionsSubscription = space.db.query(Filter.schema(FunctionDef)).subscribe((definitions) => {\n const newFunctions = getNewDefinitions(definitions.objects, registered);\n if (newFunctions.length > 0) {\n registered.push(...newFunctions);\n this.onFunctionsRegistered.emit({ space, newFunctions });\n }\n });\n this._ctx.onDispose(functionsSubscription);\n }\n });\n this._ctx.onDispose(() => spaceListSubscription.unsubscribe());\n }\n\n protected override async _close(_: Context): Promise<void> {\n this._functionBySpaceKey.clear();\n }\n}\n\nconst getNewDefinitions = <T extends { uri: string }>(candidateList: T[], existing: FunctionDef[]): T[] => {\n return candidateList.filter((candidate) => existing.find((def) => def.uri === candidate.uri) == null);\n};\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { AST, S, TypedObject } from '@dxos/echo-schema';\n\n// TODO(burdon): Factor out.\nconst omitEchoId = <T>(schema: S.Schema<T>): S.Schema<Omit<T, 'id'>> => S.make(AST.omit(schema.ast, ['id']));\n\n/**\n * Type discriminator for TriggerSpec.\n * Every spec has a type field of type FunctionTriggerType that we can use to understand which\n * type we're working with.\n * https://www.typescriptlang.org/docs/handbook/2/narrowing.html#discriminated-unions\n */\nexport type FunctionTriggerType = 'subscription' | 'timer' | 'webhook' | 'websocket';\n\nconst SubscriptionTriggerSchema = S.struct({\n type: S.literal('subscription'),\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});\nexport type SubscriptionTrigger = S.Schema.Type<typeof SubscriptionTriggerSchema>;\n\nconst TimerTriggerSchema = S.struct({\n type: S.literal('timer'),\n cron: S.string,\n});\nexport type TimerTrigger = S.Schema.Type<typeof TimerTriggerSchema>;\n\nconst WebhookTriggerSchema = S.mutable(\n S.struct({\n type: S.literal('webhook'),\n method: S.string,\n // Assigned port.\n port: S.optional(S.number),\n }),\n);\nexport type WebhookTrigger = S.Schema.Type<typeof WebhookTriggerSchema>;\n\nconst WebsocketTriggerSchema = S.struct({\n type: S.literal('websocket'),\n url: S.string,\n init: S.optional(S.record(S.string, S.any)),\n});\nexport type WebsocketTrigger = S.Schema.Type<typeof WebsocketTriggerSchema>;\n\nconst TriggerSpecSchema = S.union(\n TimerTriggerSchema,\n WebhookTriggerSchema,\n WebsocketTriggerSchema,\n SubscriptionTriggerSchema,\n);\nexport type TriggerSpec = TimerTrigger | WebhookTrigger | WebsocketTrigger | SubscriptionTrigger;\n\n/**\n * Function definition.\n */\nexport class FunctionDef extends TypedObject({\n typename: 'dxos.org/type/FunctionDef',\n version: '0.1.0',\n})({\n uri: S.string,\n description: S.optional(S.string),\n route: S.string,\n // TODO(burdon): NPM/GitHub/Docker/CF URL?\n handler: S.string,\n}) {}\n\nexport class FunctionTrigger extends TypedObject({\n typename: 'dxos.org/type/FunctionTrigger',\n version: '0.1.0',\n})({\n function: S.string.pipe(S.description('Function ID/URI.')),\n // Context passed to a function.\n meta: S.optional(S.record(S.string, S.any)),\n spec: TriggerSpecSchema,\n}) {}\n\n/**\n * Function manifest file.\n */\nexport const FunctionManifestSchema = S.struct({\n functions: S.optional(S.mutable(S.array(omitEchoId(FunctionDef)))),\n triggers: S.optional(S.mutable(S.array(omitEchoId(FunctionTrigger)))),\n});\n\nexport type FunctionManifest = S.Schema.Type<typeof FunctionManifestSchema>;\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 { Context } from '@dxos/context';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\n\nimport { type FunctionContext, type FunctionEvent, type FunctionHandler, type FunctionResponse } from '../handler';\nimport { type FunctionRegistry } from '../registry';\nimport { type FunctionDef } from '../types';\n\nexport type DevServerOptions = {\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 private _ctx = createContext();\n\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 _functionsRegistry: FunctionRegistry,\n private readonly _options: DevServerOptions,\n ) {\n this._functionsRegistry.onFunctionsRegistered.on(async ({ newFunctions }) => {\n newFunctions.forEach((def) => this._load(def));\n await this._safeUpdateRegistration();\n log('new functions loaded', { newFunctions });\n });\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 start() {\n invariant(!this._server);\n log.info('starting...');\n this._ctx = createContext();\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 });\n\n log.info('registered', { endpoint });\n this._proxy = endpoint;\n this._functionServiceRegistration = registrationId;\n\n // Open after registration, so that it can be updated with the list of function definitions.\n await this._functionsRegistry.open(this._ctx);\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 { uri, route, handler } = def;\n const filePath = join(this._options.baseDir, handler);\n log.info('loading', { uri, 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 // TODO(burdon): Import types.\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: ${uri}`);\n }\n\n this._handlers[route] = { def, handler: module.default };\n }\n\n private async _safeUpdateRegistration(): Promise<void> {\n invariant(this._functionServiceRegistration);\n try {\n await this._client.services.services.FunctionRegistryService!.updateRegistration({\n registrationId: this._functionServiceRegistration,\n functions: this.functions.map(({ def: { id, route } }) => ({ id, route })),\n });\n } catch (e) {\n log.catch(e);\n }\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\nconst createContext = () => new Context({ name: 'DevServer' });\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport path from 'node:path';\n\nimport { type Space } from '@dxos/client/echo';\nimport { Context } from '@dxos/context';\nimport { log } from '@dxos/log';\n\nimport { type FunctionEventMeta } from '../handler';\nimport { type FunctionRegistry } from '../registry';\nimport { type TriggerRegistry } from '../trigger';\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 private _ctx = createContext();\n\n constructor(\n public readonly functions: FunctionRegistry,\n public readonly triggers: TriggerRegistry,\n private readonly _options: SchedulerOptions = {},\n ) {\n this.functions.onFunctionsRegistered.on(async ({ space, newFunctions }) => {\n await this._safeActivateTriggers(space, this.triggers.getInactiveTriggers(space), newFunctions);\n });\n this.triggers.registered.on(async ({ space, triggers }) => {\n await this._safeActivateTriggers(space, triggers, this.functions.getFunctions(space));\n });\n }\n\n async start() {\n await this._ctx.dispose();\n this._ctx = createContext();\n await this.functions.open(this._ctx);\n await this.triggers.open(this._ctx);\n }\n\n async stop() {\n await this._ctx.dispose();\n await this.functions.close();\n await this.triggers.close();\n }\n\n public async register(space: Space, manifest: FunctionManifest) {\n await this.functions.register(space, manifest);\n await this.triggers.register(space, manifest);\n }\n\n private async _safeActivateTriggers(\n space: Space,\n triggers: FunctionTrigger[],\n functions: FunctionDef[],\n ): Promise<void> {\n const mountTasks = triggers.map((trigger) => {\n return this.activate(space, functions, trigger);\n });\n await Promise.all(mountTasks).catch(log.catch);\n }\n\n private async activate(space: Space, functions: FunctionDef[], fnTrigger: FunctionTrigger) {\n const definition = functions.find((def) => def.uri === fnTrigger.function);\n if (!definition) {\n log.info('function is not found for trigger', { fnTrigger });\n return;\n }\n\n await this.triggers.activate({ space }, fnTrigger, async (args) => {\n return this._execFunction(definition, {\n meta: fnTrigger.meta,\n data: { ...args, spaceKey: space.key },\n });\n });\n log('activated trigger', { space: space.key, trigger: fnTrigger });\n }\n\n private async _execFunction<TData, TMeta>(\n def: FunctionDef,\n { data, meta }: { data: TData; meta?: TMeta },\n ): Promise<number> {\n let status = 0;\n try {\n // TODO(burdon): Pass in Space key (common context)?\n const payload = Object.assign({}, meta && ({ meta } 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.route);\n log.info('exec', { function: def.uri, 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.uri });\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.uri, status });\n } catch (err: any) {\n log.error('error', { function: def.uri, error: err.message });\n status = 500;\n }\n\n return status;\n }\n}\n\nconst createContext = () => new Context({ name: 'FunctionScheduler' });\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { Event } from '@dxos/async';\nimport { type Client } from '@dxos/client';\nimport { create, Filter, type Space } from '@dxos/client/echo';\nimport { Context, Resource } from '@dxos/context';\nimport { invariant } from '@dxos/invariant';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { ComplexMap } from '@dxos/util';\n\nimport { createSubscriptionTrigger, createTimerTrigger, createWebhookTrigger, createWebsocketTrigger } from './type';\nimport { type FunctionManifest, FunctionTrigger, type FunctionTriggerType, type TriggerSpec } from '../types';\n\ntype ResponseCode = number;\n\nexport type TriggerCallback = (args: object) => Promise<ResponseCode>;\n\nexport type TriggerContext = { space: Space };\n\n// TODO(burdon): Make object?\nexport type TriggerFactory<Spec extends TriggerSpec, Options = any> = (\n ctx: Context,\n context: TriggerContext,\n spec: Spec,\n callback: TriggerCallback,\n options?: Options,\n) => Promise<void>;\n\nexport type TriggerHandlerMap = { [type in FunctionTriggerType]: TriggerFactory<any> };\n\nconst triggerHandlers: TriggerHandlerMap = {\n subscription: createSubscriptionTrigger,\n timer: createTimerTrigger,\n webhook: createWebhookTrigger,\n websocket: createWebsocketTrigger,\n};\n\nexport type TriggerEvent = {\n space: Space;\n triggers: FunctionTrigger[];\n};\n\ntype RegisteredTrigger = {\n activationCtx?: Context;\n trigger: FunctionTrigger;\n};\n\nexport class TriggerRegistry extends Resource {\n private readonly _triggersBySpaceKey = new ComplexMap<PublicKey, RegisteredTrigger[]>(PublicKey.hash);\n\n public readonly registered = new Event<TriggerEvent>();\n public readonly removed = new Event<TriggerEvent>();\n\n constructor(\n private readonly _client: Client,\n private readonly _options?: TriggerHandlerMap,\n ) {\n super();\n }\n\n public getActiveTriggers(space: Space): FunctionTrigger[] {\n return this._getTriggers(space, (t) => t.activationCtx != null);\n }\n\n public getInactiveTriggers(space: Space): FunctionTrigger[] {\n return this._getTriggers(space, (t) => t.activationCtx == null);\n }\n\n async activate(triggerCtx: TriggerContext, trigger: FunctionTrigger, callback: TriggerCallback): Promise<void> {\n log('activate', { space: triggerCtx.space.key, trigger });\n const activationCtx = new Context({ name: `trigger_${trigger.function}` });\n this._ctx.onDispose(() => activationCtx.dispose());\n const registeredTrigger = this._triggersBySpaceKey\n .get(triggerCtx.space.key)\n ?.find((reg) => reg.trigger.id === trigger.id);\n invariant(registeredTrigger, `Trigger is not registered: ${trigger.function}`);\n registeredTrigger.activationCtx = activationCtx;\n\n try {\n const options = this._options?.[trigger.spec.type];\n await triggerHandlers[trigger.spec.type](activationCtx, triggerCtx, trigger.spec, callback, options);\n } catch (err) {\n delete registeredTrigger.activationCtx;\n throw err;\n }\n }\n\n /**\n * Loads triggers from the manifest into the space.\n */\n public async register(space: Space, manifest: FunctionManifest): Promise<void> {\n log('register', { space: space.key });\n if (!manifest.triggers?.length) {\n return;\n }\n if (!space.db.graph.runtimeSchemaRegistry.isSchemaRegistered(FunctionTrigger)) {\n space.db.graph.runtimeSchemaRegistry.registerSchema(FunctionTrigger);\n }\n\n const reactiveObjects = manifest.triggers.map((template: Omit<FunctionTrigger, 'id'>) =>\n create(FunctionTrigger, { ...template }),\n );\n reactiveObjects.forEach((obj) => space.db.add(obj));\n }\n\n protected override async _open(): Promise<void> {\n const spaceListSubscription = this._client.spaces.subscribe(async (spaces) => {\n for (const space of spaces) {\n if (this._triggersBySpaceKey.has(space.key)) {\n continue;\n }\n\n const registered: RegisteredTrigger[] = [];\n this._triggersBySpaceKey.set(space.key, registered);\n await space.waitUntilReady();\n if (this._ctx.disposed) {\n break;\n }\n const functionsSubscription = space.db.query(Filter.schema(FunctionTrigger)).subscribe(async (triggers) => {\n await this._handleRemovedTriggers(space, triggers.objects, registered);\n this._handleNewTriggers(space, triggers.objects, registered);\n });\n\n this._ctx.onDispose(functionsSubscription);\n }\n });\n\n this._ctx.onDispose(() => spaceListSubscription.unsubscribe());\n }\n\n protected override async _close(_: Context): Promise<void> {\n this._triggersBySpaceKey.clear();\n }\n\n private _handleNewTriggers(space: Space, allTriggers: FunctionTrigger[], registered: RegisteredTrigger[]) {\n const newTriggers = allTriggers.filter((candidate) => {\n return registered.find((reg) => reg.trigger.id === candidate.id) == null;\n });\n\n if (newTriggers.length > 0) {\n const newRegisteredTriggers: RegisteredTrigger[] = newTriggers.map((trigger) => ({ trigger }));\n registered.push(...newRegisteredTriggers);\n log('registered new triggers', () => ({ spaceKey: space.key, functions: newTriggers.map((t) => t.function) }));\n this.registered.emit({ space, triggers: newTriggers });\n }\n }\n\n private async _handleRemovedTriggers(\n space: Space,\n allTriggers: FunctionTrigger[],\n registered: RegisteredTrigger[],\n ): Promise<void> {\n const removed: FunctionTrigger[] = [];\n for (let i = registered.length - 1; i >= 0; i--) {\n const wasRemoved =\n allTriggers.find((trigger: FunctionTrigger) => trigger.id === registered[i].trigger.id) == null;\n if (wasRemoved) {\n const unregistered = registered.splice(i, 1)[0];\n await unregistered.activationCtx?.dispose();\n removed.push(unregistered.trigger);\n }\n }\n\n if (removed.length > 0) {\n this.removed.emit({ space, triggers: removed });\n }\n }\n\n private _getTriggers(space: Space, predicate: (trigger: RegisteredTrigger) => boolean): FunctionTrigger[] {\n const allSpaceTriggers = this._triggersBySpaceKey.get(space.key) ?? [];\n return allSpaceTriggers.filter(predicate).map((trigger) => trigger.trigger);\n }\n}\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { TextV0Type } from '@braneframe/types';\nimport { debounce, DeferredTask } from '@dxos/async';\nimport { type Context } from '@dxos/context';\nimport { createSubscription, Filter, getAutomergeObjectCore, type Query } from '@dxos/echo-db';\nimport { log } from '@dxos/log';\n\nimport type { SubscriptionTrigger } from '../../types';\nimport { type TriggerCallback, type TriggerContext, type TriggerFactory } from '../trigger-registry';\n\nexport const createSubscriptionTrigger: TriggerFactory<SubscriptionTrigger> = async (\n ctx: Context,\n triggerCtx: TriggerContext,\n spec: SubscriptionTrigger,\n callback: TriggerCallback,\n) => {\n const objectIds = new Set<string>();\n const task = new DeferredTask(ctx, async () => {\n if (objectIds.size > 0) {\n await callback({ objects: Array.from(objectIds) });\n objectIds.clear();\n }\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 = triggerCtx.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// Copyright 2024 DXOS.org\n//\n\nimport { CronJob } from 'cron';\n\nimport { DeferredTask } from '@dxos/async';\nimport { type Context } from '@dxos/context';\nimport { log } from '@dxos/log';\n\nimport type { TimerTrigger } from '../../types';\nimport { type TriggerCallback, type TriggerContext, type TriggerFactory } from '../trigger-registry';\n\nexport const createTimerTrigger: TriggerFactory<TimerTrigger> = async (\n ctx: Context,\n triggerContext: TriggerContext,\n spec: TimerTrigger,\n callback: TriggerCallback,\n) => {\n const task = new DeferredTask(ctx, async () => {\n await callback({});\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: triggerContext.space.key.truncate(), count: run, delta });\n task.schedule();\n },\n });\n\n job.start();\n ctx.onDispose(() => job.stop());\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { getPort } from 'get-port-please';\nimport http from 'node:http';\n\nimport { type Context } from '@dxos/context';\nimport { log } from '@dxos/log';\n\nimport type { WebhookTrigger } from '../../types';\nimport { type TriggerCallback, type TriggerContext, type TriggerFactory } from '../trigger-registry';\n\nexport const createWebhookTrigger: TriggerFactory<WebhookTrigger> = async (\n ctx: Context,\n _: TriggerContext,\n spec: WebhookTrigger,\n callback: TriggerCallback,\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 res.statusCode = await callback({});\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// Copyright 2024 DXOS.org\n//\n\nimport WebSocket from 'ws';\n\nimport { sleep, Trigger } from '@dxos/async';\nimport { type Context } from '@dxos/context';\nimport { log } from '@dxos/log';\n\nimport { type WebsocketTrigger } from '../../types';\nimport { type TriggerCallback, type TriggerContext, type TriggerFactory } from '../trigger-registry';\n\ninterface WebsocketTriggerOptions {\n retryDelay: number;\n maxAttempts: number;\n}\n\n/**\n * Websocket.\n * NOTE: The port must be unique, so the same hook cannot be used for multiple spaces.\n */\nexport const createWebsocketTrigger: TriggerFactory<WebsocketTrigger, WebsocketTriggerOptions> = async (\n ctx: Context,\n triggerCtx: TriggerContext,\n spec: WebsocketTrigger,\n callback: TriggerCallback,\n options: WebsocketTriggerOptions = { retryDelay: 2, maxAttempts: 5 },\n) => {\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 createWebsocketTrigger(ctx, triggerCtx, spec, callback, 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 log.info('message');\n const data = JSON.parse(new TextDecoder().decode(event.data as Uint8Array));\n await callback({ 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"],
|
|
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", "Event", "create", "Filter", "Resource", "PublicKey", "ComplexMap", "AST", "S", "TypedObject", "omitEchoId", "schema", "S", "make", "AST", "omit", "ast", "SubscriptionTriggerSchema", "struct", "type", "literal", "filter", "array", "string", "props", "optional", "record", "any", "options", "deep", "boolean", "delay", "number", "TimerTriggerSchema", "cron", "WebhookTriggerSchema", "mutable", "method", "port", "WebsocketTriggerSchema", "url", "init", "TriggerSpecSchema", "union", "FunctionDef", "TypedObject", "typename", "version", "uri", "description", "route", "handler", "FunctionTrigger", "function", "pipe", "meta", "spec", "FunctionManifestSchema", "functions", "triggers", "FunctionRegistry", "Resource", "constructor", "_client", "_functionBySpaceKey", "ComplexMap", "PublicKey", "hash", "onFunctionsRegistered", "Event", "getFunctions", "space", "get", "key", "register", "manifest", "functions", "length", "db", "graph", "runtimeSchemaRegistry", "isSchemaRegistered", "FunctionDef", "registerSchema", "objects", "existingDefinitions", "query", "Filter", "schema", "run", "newDefinitions", "getNewDefinitions", "reactiveObjects", "map", "template", "create", "forEach", "obj", "add", "_open", "spaceListSubscription", "spaces", "subscribe", "has", "registered", "set", "waitUntilReady", "_ctx", "disposed", "functionsSubscription", "definitions", "newFunctions", "push", "emit", "onDispose", "unsubscribe", "_close", "_", "clear", "candidateList", "existing", "filter", "candidate", "find", "def", "uri", "express", "getPort", "join", "Event", "Trigger", "Context", "invariant", "log", "DevServer", "constructor", "_client", "_functionsRegistry", "_options", "_ctx", "createContext", "_handlers", "_seq", "update", "Event", "onFunctionsRegistered", "on", "newFunctions", "forEach", "def", "_load", "_safeUpdateRegistration", "log", "stats", "seq", "endpoint", "invariant", "_port", "proxy", "_proxy", "functions", "Object", "values", "start", "_server", "info", "app", "express", "use", "json", "post", "req", "res", "path", "params", "reload", "statusCode", "invoke", "body", "end", "err", "catch", "getPort", "host", "port", "portRange", "listen", "registrationId", "services", "FunctionRegistryService", "register", "_functionServiceRegistration", "open", "stop", "Error", "trigger", "Trigger", "close", "unregister", "undefined", "wake", "throw", "wait", "force", "uri", "route", "handler", "filePath", "join", "baseDir", "keys", "require", "cache", "filter", "key", "startsWith", "module", "default", "updateRegistration", "map", "id", "e", "data", "now", "Date", "_invoke", "duration", "emit", "event", "context", "client", "dataDir", "response", "status", "code", "Context", "name", "path", "Context", "log", "Scheduler", "constructor", "functions", "triggers", "_options", "_ctx", "createContext", "onFunctionsRegistered", "on", "space", "newFunctions", "_safeActivateTriggers", "getInactiveTriggers", "registered", "getFunctions", "start", "dispose", "open", "stop", "close", "register", "manifest", "mountTasks", "map", "trigger", "activate", "Promise", "all", "catch", "fnTrigger", "definition", "find", "def", "uri", "function", "info", "args", "_execFunction", "meta", "data", "spaceKey", "key", "status", "payload", "Object", "assign", "endpoint", "callback", "url", "join", "route", "response", "fetch", "method", "headers", "body", "JSON", "stringify", "Error", "err", "error", "message", "name", "Event", "create", "Filter", "Context", "Resource", "invariant", "PublicKey", "log", "ComplexMap", "TextV0Type", "debounce", "DeferredTask", "createSubscription", "Filter", "getAutomergeObjectCore", "log", "createSubscriptionTrigger", "ctx", "triggerCtx", "spec", "callback", "objectIds", "Set", "task", "size", "objects", "Array", "from", "clear", "subscriptions", "subscription", "added", "updated", "info", "length", "object", "add", "id", "schedule", "push", "unsubscribe", "filter", "options", "deep", "delay", "update", "content", "updates", "on", "query", "space", "db", "or", "map", "type", "props", "typename", "subscribe", "onDispose", "forEach", "CronJob", "DeferredTask", "log", "createTimerTrigger", "ctx", "triggerContext", "spec", "callback", "task", "last", "run", "job", "from", "cronTime", "cron", "runOnInit", "onTick", "now", "Date", "delta", "info", "space", "key", "truncate", "count", "schedule", "start", "onDispose", "stop", "getPort", "http", "log", "createWebhookTrigger", "ctx", "_", "spec", "callback", "server", "createServer", "req", "res", "method", "statusCode", "end", "port", "random", "listen", "info", "onDispose", "close", "WebSocket", "sleep", "Trigger", "log", "createWebsocketTrigger", "ctx", "triggerCtx", "spec", "callback", "options", "retryDelay", "maxAttempts", "url", "init", "ws", "attempt", "open", "Object", "assign", "onopen", "info", "send", "TextEncoder", "encode", "JSON", "stringify", "wake", "onclose", "event", "code", "setTimeout", "onerror", "catch", "error", "onmessage", "data", "parse", "TextDecoder", "decode", "err", "isOpen", "wait", "Math", "pow", "warn", "onDispose", "close", "triggerHandlers", "subscription", "createSubscriptionTrigger", "timer", "createTimerTrigger", "webhook", "createWebhookTrigger", "websocket", "createWebsocketTrigger", "TriggerRegistry", "Resource", "constructor", "_client", "_options", "_triggersBySpaceKey", "ComplexMap", "PublicKey", "hash", "registered", "Event", "removed", "getActiveTriggers", "space", "_getTriggers", "t", "activationCtx", "getInactiveTriggers", "activate", "triggerCtx", "trigger", "callback", "log", "key", "Context", "name", "function", "_ctx", "onDispose", "dispose", "registeredTrigger", "get", "find", "reg", "id", "invariant", "options", "spec", "type", "err", "register", "manifest", "triggers", "length", "db", "graph", "runtimeSchemaRegistry", "isSchemaRegistered", "FunctionTrigger", "registerSchema", "reactiveObjects", "map", "template", "create", "forEach", "obj", "add", "_open", "spaceListSubscription", "spaces", "subscribe", "has", "set", "waitUntilReady", "disposed", "functionsSubscription", "query", "Filter", "schema", "_handleRemovedTriggers", "objects", "_handleNewTriggers", "unsubscribe", "_close", "_", "clear", "allTriggers", "newTriggers", "filter", "candidate", "newRegisteredTriggers", "push", "spaceKey", "functions", "emit", "i", "wasRemoved", "unregistered", "splice", "predicate", "allSpaceTriggers"]
|
|
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":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/types.ts":{"bytes":9313,"imports":[{"path":"@dxos/echo-schema","kind":"import-statement","external":true},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/core/functions/src/registry/function-registry.ts":{"bytes":11255,"imports":[{"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/keys","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"packages/core/functions/src/types.ts","kind":"import-statement","original":"../types"},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/core/functions/src/registry/index.ts":{"bytes":497,"imports":[{"path":"packages/core/functions/src/registry/function-registry.ts","kind":"import-statement","original":"./function-registry"},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/core/functions/src/runtime/dev-server.ts":{"bytes":27510,"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/context","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":15341,"imports":[{"path":"@dxos/node-std/path","kind":"import-statement","external":true},{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/log","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/trigger/type/subscription-trigger.ts":{"bytes":9356,"imports":[{"path":"@braneframe/types","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/echo-db","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/core/functions/src/trigger/type/timer-trigger.ts":{"bytes":4169,"imports":[{"path":"cron","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/core/functions/src/trigger/type/webhook-trigger.ts":{"bytes":4272,"imports":[{"path":"get-port-please","kind":"import-statement","external":true},{"path":"@dxos/node-std/http","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/core/functions/src/trigger/type/websocket-trigger.ts":{"bytes":10377,"imports":[{"path":"ws","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/core/functions/src/trigger/type/index.ts":{"bytes":829,"imports":[{"path":"packages/core/functions/src/trigger/type/subscription-trigger.ts","kind":"import-statement","original":"./subscription-trigger"},{"path":"packages/core/functions/src/trigger/type/timer-trigger.ts","kind":"import-statement","original":"./timer-trigger"},{"path":"packages/core/functions/src/trigger/type/webhook-trigger.ts","kind":"import-statement","original":"./webhook-trigger"},{"path":"packages/core/functions/src/trigger/type/websocket-trigger.ts","kind":"import-statement","original":"./websocket-trigger"},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/core/functions/src/trigger/trigger-registry.ts":{"bytes":21823,"imports":[{"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/keys","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"packages/core/functions/src/trigger/type/index.ts","kind":"import-statement","original":"./type"},{"path":"packages/core/functions/src/types.ts","kind":"import-statement","original":"../types"},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/core/functions/src/trigger/index.ts":{"bytes":495,"imports":[{"path":"packages/core/functions/src/trigger/trigger-registry.ts","kind":"import-statement","original":"./trigger-registry"},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/core/functions/src/index.ts":{"bytes":801,"imports":[{"path":"packages/core/functions/src/handler.ts","kind":"import-statement","original":"./handler"},{"path":"packages/core/functions/src/registry/index.ts","kind":"import-statement","original":"./registry"},{"path":"packages/core/functions/src/runtime/index.ts","kind":"import-statement","original":"./runtime"},{"path":"packages/core/functions/src/trigger/index.ts","kind":"import-statement","original":"./trigger"},{"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":59026},"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":"@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/keys","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"@dxos/echo-schema","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/context","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/node-std/path","kind":"import-statement","external":true},{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/log","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/keys","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"@braneframe/types","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/echo-db","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"cron","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/log","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/log","kind":"import-statement","external":true},{"path":"ws","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true}],"exports":["DevServer","FunctionDef","FunctionManifestSchema","FunctionRegistry","FunctionTrigger","Scheduler","TriggerRegistry","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/registry/function-registry.ts":{"bytesInOutput":2596},"packages/core/functions/src/types.ts":{"bytesInOutput":1789},"packages/core/functions/src/registry/index.ts":{"bytesInOutput":0},"packages/core/functions/src/runtime/dev-server.ts":{"bytesInOutput":7829},"packages/core/functions/src/runtime/index.ts":{"bytesInOutput":0},"packages/core/functions/src/runtime/scheduler.ts":{"bytesInOutput":3837},"packages/core/functions/src/trigger/trigger-registry.ts":{"bytesInOutput":5257},"packages/core/functions/src/trigger/type/subscription-trigger.ts":{"bytesInOutput":2083},"packages/core/functions/src/trigger/type/index.ts":{"bytesInOutput":0},"packages/core/functions/src/trigger/type/timer-trigger.ts":{"bytesInOutput":940},"packages/core/functions/src/trigger/type/webhook-trigger.ts":{"bytesInOutput":835},"packages/core/functions/src/trigger/type/websocket-trigger.ts":{"bytesInOutput":2847},"packages/core/functions/src/trigger/index.ts":{"bytesInOutput":0}},"bytes":30554}}}
|
|
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/types.ts":{"bytes":9313,"imports":[{"path":"@dxos/echo-schema","kind":"import-statement","external":true},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/core/functions/src/registry/function-registry.ts":{"bytes":11292,"imports":[{"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/keys","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"packages/core/functions/src/types.ts","kind":"import-statement","original":"../types"},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/core/functions/src/registry/index.ts":{"bytes":497,"imports":[{"path":"packages/core/functions/src/registry/function-registry.ts","kind":"import-statement","original":"./function-registry"},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/core/functions/src/runtime/dev-server.ts":{"bytes":27510,"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/context","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":15341,"imports":[{"path":"@dxos/node-std/path","kind":"import-statement","external":true},{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/log","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/trigger/type/subscription-trigger.ts":{"bytes":9356,"imports":[{"path":"@braneframe/types","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/echo-db","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/core/functions/src/trigger/type/timer-trigger.ts":{"bytes":4169,"imports":[{"path":"cron","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/core/functions/src/trigger/type/webhook-trigger.ts":{"bytes":4272,"imports":[{"path":"get-port-please","kind":"import-statement","external":true},{"path":"@dxos/node-std/http","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/core/functions/src/trigger/type/websocket-trigger.ts":{"bytes":10377,"imports":[{"path":"ws","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/core/functions/src/trigger/type/index.ts":{"bytes":829,"imports":[{"path":"packages/core/functions/src/trigger/type/subscription-trigger.ts","kind":"import-statement","original":"./subscription-trigger"},{"path":"packages/core/functions/src/trigger/type/timer-trigger.ts","kind":"import-statement","original":"./timer-trigger"},{"path":"packages/core/functions/src/trigger/type/webhook-trigger.ts","kind":"import-statement","original":"./webhook-trigger"},{"path":"packages/core/functions/src/trigger/type/websocket-trigger.ts","kind":"import-statement","original":"./websocket-trigger"},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/core/functions/src/trigger/trigger-registry.ts":{"bytes":21856,"imports":[{"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/keys","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"packages/core/functions/src/trigger/type/index.ts","kind":"import-statement","original":"./type"},{"path":"packages/core/functions/src/types.ts","kind":"import-statement","original":"../types"},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/core/functions/src/trigger/index.ts":{"bytes":495,"imports":[{"path":"packages/core/functions/src/trigger/trigger-registry.ts","kind":"import-statement","original":"./trigger-registry"},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/core/functions/src/index.ts":{"bytes":801,"imports":[{"path":"packages/core/functions/src/handler.ts","kind":"import-statement","original":"./handler"},{"path":"packages/core/functions/src/registry/index.ts","kind":"import-statement","original":"./registry"},{"path":"packages/core/functions/src/runtime/index.ts","kind":"import-statement","original":"./runtime"},{"path":"packages/core/functions/src/trigger/index.ts","kind":"import-statement","original":"./trigger"},{"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":59066},"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":"@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/keys","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"@dxos/echo-schema","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/context","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/node-std/path","kind":"import-statement","external":true},{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/log","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/keys","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"@braneframe/types","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/echo-db","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"cron","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/log","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/log","kind":"import-statement","external":true},{"path":"ws","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true}],"exports":["DevServer","FunctionDef","FunctionManifestSchema","FunctionRegistry","FunctionTrigger","Scheduler","TriggerRegistry","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/registry/function-registry.ts":{"bytesInOutput":2605},"packages/core/functions/src/types.ts":{"bytesInOutput":1789},"packages/core/functions/src/registry/index.ts":{"bytesInOutput":0},"packages/core/functions/src/runtime/dev-server.ts":{"bytesInOutput":7829},"packages/core/functions/src/runtime/index.ts":{"bytesInOutput":0},"packages/core/functions/src/runtime/scheduler.ts":{"bytesInOutput":3837},"packages/core/functions/src/trigger/trigger-registry.ts":{"bytesInOutput":5266},"packages/core/functions/src/trigger/type/subscription-trigger.ts":{"bytesInOutput":2083},"packages/core/functions/src/trigger/type/index.ts":{"bytesInOutput":0},"packages/core/functions/src/trigger/type/timer-trigger.ts":{"bytesInOutput":940},"packages/core/functions/src/trigger/type/webhook-trigger.ts":{"bytesInOutput":835},"packages/core/functions/src/trigger/type/websocket-trigger.ts":{"bytesInOutput":2847},"packages/core/functions/src/trigger/index.ts":{"bytesInOutput":0}},"bytes":30572}}}
|
package/dist/lib/node/index.cjs
CHANGED
|
@@ -200,7 +200,7 @@ var FunctionRegistry = class extends import_context.Resource {
|
|
|
200
200
|
if (!manifest.functions?.length) {
|
|
201
201
|
return;
|
|
202
202
|
}
|
|
203
|
-
if (!space.db.graph.runtimeSchemaRegistry.
|
|
203
|
+
if (!space.db.graph.runtimeSchemaRegistry.isSchemaRegistered(FunctionDef)) {
|
|
204
204
|
space.db.graph.runtimeSchemaRegistry.registerSchema(FunctionDef);
|
|
205
205
|
}
|
|
206
206
|
const { objects: existingDefinitions } = await space.db.query(import_echo.Filter.schema(FunctionDef)).run();
|
|
@@ -990,7 +990,7 @@ var TriggerRegistry = class extends import_context4.Resource {
|
|
|
990
990
|
if (!manifest.triggers?.length) {
|
|
991
991
|
return;
|
|
992
992
|
}
|
|
993
|
-
if (!space.db.graph.runtimeSchemaRegistry.
|
|
993
|
+
if (!space.db.graph.runtimeSchemaRegistry.isSchemaRegistered(FunctionTrigger)) {
|
|
994
994
|
space.db.graph.runtimeSchemaRegistry.registerSchema(FunctionTrigger);
|
|
995
995
|
}
|
|
996
996
|
const reactiveObjects = manifest.triggers.map((template) => (0, import_echo2.create)(FunctionTrigger, {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/handler.ts", "../../../src/registry/function-registry.ts", "../../../src/types.ts", "../../../src/runtime/dev-server.ts", "../../../src/runtime/scheduler.ts", "../../../src/trigger/trigger-registry.ts", "../../../src/trigger/type/subscription-trigger.ts", "../../../src/trigger/type/timer-trigger.ts", "../../../src/trigger/type/webhook-trigger.ts", "../../../src/trigger/type/websocket-trigger.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 2024 DXOS.org\n//\n\nimport { Event } from '@dxos/async';\nimport { type Client } from '@dxos/client';\nimport { create, Filter, type Space } from '@dxos/client/echo';\nimport { type Context, Resource } from '@dxos/context';\nimport { PublicKey } from '@dxos/keys';\nimport { ComplexMap } from '@dxos/util';\n\nimport { FunctionDef, type FunctionManifest } from '../types';\n\nexport type FunctionsRegisteredEvent = {\n space: Space;\n newFunctions: FunctionDef[];\n};\n\nexport class FunctionRegistry extends Resource {\n private readonly _functionBySpaceKey = new ComplexMap<PublicKey, FunctionDef[]>(PublicKey.hash);\n\n public readonly onFunctionsRegistered = new Event<FunctionsRegisteredEvent>();\n\n constructor(private readonly _client: Client) {\n super();\n }\n\n public getFunctions(space: Space): FunctionDef[] {\n return this._functionBySpaceKey.get(space.key) ?? [];\n }\n\n /**\n * The method loads function definitions from the manifest into the space.\n * We first load all the definitions from the space to deduplicate by functionId.\n */\n // TODO(burdon): This should not be space specific (they are static for the agent).\n public async register(space: Space, manifest: FunctionManifest): Promise<void> {\n if (!manifest.functions?.length) {\n return;\n }\n if (!space.db.graph.runtimeSchemaRegistry.hasSchema(FunctionDef)) {\n space.db.graph.runtimeSchemaRegistry.registerSchema(FunctionDef);\n }\n\n const { objects: existingDefinitions } = await space.db.query(Filter.schema(FunctionDef)).run();\n const newDefinitions = getNewDefinitions(manifest.functions, existingDefinitions);\n const reactiveObjects = newDefinitions.map((template) => create(FunctionDef, { ...template }));\n reactiveObjects.forEach((obj) => space.db.add(obj));\n }\n\n protected override async _open(): Promise<void> {\n const spaceListSubscription = this._client.spaces.subscribe(async (spaces) => {\n for (const space of spaces) {\n if (this._functionBySpaceKey.has(space.key)) {\n continue;\n }\n const registered: FunctionDef[] = [];\n this._functionBySpaceKey.set(space.key, registered);\n await space.waitUntilReady();\n if (this._ctx.disposed) {\n break;\n }\n\n const functionsSubscription = space.db.query(Filter.schema(FunctionDef)).subscribe((definitions) => {\n const newFunctions = getNewDefinitions(definitions.objects, registered);\n if (newFunctions.length > 0) {\n registered.push(...newFunctions);\n this.onFunctionsRegistered.emit({ space, newFunctions });\n }\n });\n this._ctx.onDispose(functionsSubscription);\n }\n });\n this._ctx.onDispose(() => spaceListSubscription.unsubscribe());\n }\n\n protected override async _close(_: Context): Promise<void> {\n this._functionBySpaceKey.clear();\n }\n}\n\nconst getNewDefinitions = <T extends { uri: string }>(candidateList: T[], existing: FunctionDef[]): T[] => {\n return candidateList.filter((candidate) => existing.find((def) => def.uri === candidate.uri) == null);\n};\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { AST, S, TypedObject } from '@dxos/echo-schema';\n\n// TODO(burdon): Factor out.\nconst omitEchoId = <T>(schema: S.Schema<T>): S.Schema<Omit<T, 'id'>> => S.make(AST.omit(schema.ast, ['id']));\n\n/**\n * Type discriminator for TriggerSpec.\n * Every spec has a type field of type FunctionTriggerType that we can use to understand which\n * type we're working with.\n * https://www.typescriptlang.org/docs/handbook/2/narrowing.html#discriminated-unions\n */\nexport type FunctionTriggerType = 'subscription' | 'timer' | 'webhook' | 'websocket';\n\nconst SubscriptionTriggerSchema = S.struct({\n type: S.literal('subscription'),\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});\nexport type SubscriptionTrigger = S.Schema.Type<typeof SubscriptionTriggerSchema>;\n\nconst TimerTriggerSchema = S.struct({\n type: S.literal('timer'),\n cron: S.string,\n});\nexport type TimerTrigger = S.Schema.Type<typeof TimerTriggerSchema>;\n\nconst WebhookTriggerSchema = S.mutable(\n S.struct({\n type: S.literal('webhook'),\n method: S.string,\n // Assigned port.\n port: S.optional(S.number),\n }),\n);\nexport type WebhookTrigger = S.Schema.Type<typeof WebhookTriggerSchema>;\n\nconst WebsocketTriggerSchema = S.struct({\n type: S.literal('websocket'),\n url: S.string,\n init: S.optional(S.record(S.string, S.any)),\n});\nexport type WebsocketTrigger = S.Schema.Type<typeof WebsocketTriggerSchema>;\n\nconst TriggerSpecSchema = S.union(\n TimerTriggerSchema,\n WebhookTriggerSchema,\n WebsocketTriggerSchema,\n SubscriptionTriggerSchema,\n);\nexport type TriggerSpec = TimerTrigger | WebhookTrigger | WebsocketTrigger | SubscriptionTrigger;\n\n/**\n * Function definition.\n */\nexport class FunctionDef extends TypedObject({\n typename: 'dxos.org/type/FunctionDef',\n version: '0.1.0',\n})({\n uri: S.string,\n description: S.optional(S.string),\n route: S.string,\n // TODO(burdon): NPM/GitHub/Docker/CF URL?\n handler: S.string,\n}) {}\n\nexport class FunctionTrigger extends TypedObject({\n typename: 'dxos.org/type/FunctionTrigger',\n version: '0.1.0',\n})({\n function: S.string.pipe(S.description('Function ID/URI.')),\n // Context passed to a function.\n meta: S.optional(S.record(S.string, S.any)),\n spec: TriggerSpecSchema,\n}) {}\n\n/**\n * Function manifest file.\n */\nexport const FunctionManifestSchema = S.struct({\n functions: S.optional(S.mutable(S.array(omitEchoId(FunctionDef)))),\n triggers: S.optional(S.mutable(S.array(omitEchoId(FunctionTrigger)))),\n});\n\nexport type FunctionManifest = S.Schema.Type<typeof FunctionManifestSchema>;\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 { Context } from '@dxos/context';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\n\nimport { type FunctionContext, type FunctionEvent, type FunctionHandler, type FunctionResponse } from '../handler';\nimport { type FunctionRegistry } from '../registry';\nimport { type FunctionDef } from '../types';\n\nexport type DevServerOptions = {\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 private _ctx = createContext();\n\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 _functionsRegistry: FunctionRegistry,\n private readonly _options: DevServerOptions,\n ) {\n this._functionsRegistry.onFunctionsRegistered.on(async ({ newFunctions }) => {\n newFunctions.forEach((def) => this._load(def));\n await this._safeUpdateRegistration();\n log('new functions loaded', { newFunctions });\n });\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 start() {\n invariant(!this._server);\n log.info('starting...');\n this._ctx = createContext();\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 });\n\n log.info('registered', { endpoint });\n this._proxy = endpoint;\n this._functionServiceRegistration = registrationId;\n\n // Open after registration, so that it can be updated with the list of function definitions.\n await this._functionsRegistry.open(this._ctx);\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 { uri, route, handler } = def;\n const filePath = join(this._options.baseDir, handler);\n log.info('loading', { uri, 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 // TODO(burdon): Import types.\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: ${uri}`);\n }\n\n this._handlers[route] = { def, handler: module.default };\n }\n\n private async _safeUpdateRegistration(): Promise<void> {\n invariant(this._functionServiceRegistration);\n try {\n await this._client.services.services.FunctionRegistryService!.updateRegistration({\n registrationId: this._functionServiceRegistration,\n functions: this.functions.map(({ def: { id, route } }) => ({ id, route })),\n });\n } catch (e) {\n log.catch(e);\n }\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\nconst createContext = () => new Context({ name: 'DevServer' });\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport path from 'node:path';\n\nimport { type Space } from '@dxos/client/echo';\nimport { Context } from '@dxos/context';\nimport { log } from '@dxos/log';\n\nimport { type FunctionEventMeta } from '../handler';\nimport { type FunctionRegistry } from '../registry';\nimport { type TriggerRegistry } from '../trigger';\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 private _ctx = createContext();\n\n constructor(\n public readonly functions: FunctionRegistry,\n public readonly triggers: TriggerRegistry,\n private readonly _options: SchedulerOptions = {},\n ) {\n this.functions.onFunctionsRegistered.on(async ({ space, newFunctions }) => {\n await this._safeActivateTriggers(space, this.triggers.getInactiveTriggers(space), newFunctions);\n });\n this.triggers.registered.on(async ({ space, triggers }) => {\n await this._safeActivateTriggers(space, triggers, this.functions.getFunctions(space));\n });\n }\n\n async start() {\n await this._ctx.dispose();\n this._ctx = createContext();\n await this.functions.open(this._ctx);\n await this.triggers.open(this._ctx);\n }\n\n async stop() {\n await this._ctx.dispose();\n await this.functions.close();\n await this.triggers.close();\n }\n\n public async register(space: Space, manifest: FunctionManifest) {\n await this.functions.register(space, manifest);\n await this.triggers.register(space, manifest);\n }\n\n private async _safeActivateTriggers(\n space: Space,\n triggers: FunctionTrigger[],\n functions: FunctionDef[],\n ): Promise<void> {\n const mountTasks = triggers.map((trigger) => {\n return this.activate(space, functions, trigger);\n });\n await Promise.all(mountTasks).catch(log.catch);\n }\n\n private async activate(space: Space, functions: FunctionDef[], fnTrigger: FunctionTrigger) {\n const definition = functions.find((def) => def.uri === fnTrigger.function);\n if (!definition) {\n log.info('function is not found for trigger', { fnTrigger });\n return;\n }\n\n await this.triggers.activate({ space }, fnTrigger, async (args) => {\n return this._execFunction(definition, {\n meta: fnTrigger.meta,\n data: { ...args, spaceKey: space.key },\n });\n });\n log('activated trigger', { space: space.key, trigger: fnTrigger });\n }\n\n private async _execFunction<TData, TMeta>(\n def: FunctionDef,\n { data, meta }: { data: TData; meta?: TMeta },\n ): Promise<number> {\n let status = 0;\n try {\n // TODO(burdon): Pass in Space key (common context)?\n const payload = Object.assign({}, meta && ({ meta } 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.route);\n log.info('exec', { function: def.uri, 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.uri });\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.uri, status });\n } catch (err: any) {\n log.error('error', { function: def.uri, error: err.message });\n status = 500;\n }\n\n return status;\n }\n}\n\nconst createContext = () => new Context({ name: 'FunctionScheduler' });\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { Event } from '@dxos/async';\nimport { type Client } from '@dxos/client';\nimport { create, Filter, type Space } from '@dxos/client/echo';\nimport { Context, Resource } from '@dxos/context';\nimport { invariant } from '@dxos/invariant';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { ComplexMap } from '@dxos/util';\n\nimport { createSubscriptionTrigger, createTimerTrigger, createWebhookTrigger, createWebsocketTrigger } from './type';\nimport { type FunctionManifest, FunctionTrigger, type FunctionTriggerType, type TriggerSpec } from '../types';\n\ntype ResponseCode = number;\n\nexport type TriggerCallback = (args: object) => Promise<ResponseCode>;\n\nexport type TriggerContext = { space: Space };\n\n// TODO(burdon): Make object?\nexport type TriggerFactory<Spec extends TriggerSpec, Options = any> = (\n ctx: Context,\n context: TriggerContext,\n spec: Spec,\n callback: TriggerCallback,\n options?: Options,\n) => Promise<void>;\n\nexport type TriggerHandlerMap = { [type in FunctionTriggerType]: TriggerFactory<any> };\n\nconst triggerHandlers: TriggerHandlerMap = {\n subscription: createSubscriptionTrigger,\n timer: createTimerTrigger,\n webhook: createWebhookTrigger,\n websocket: createWebsocketTrigger,\n};\n\nexport type TriggerEvent = {\n space: Space;\n triggers: FunctionTrigger[];\n};\n\ntype RegisteredTrigger = {\n activationCtx?: Context;\n trigger: FunctionTrigger;\n};\n\nexport class TriggerRegistry extends Resource {\n private readonly _triggersBySpaceKey = new ComplexMap<PublicKey, RegisteredTrigger[]>(PublicKey.hash);\n\n public readonly registered = new Event<TriggerEvent>();\n public readonly removed = new Event<TriggerEvent>();\n\n constructor(\n private readonly _client: Client,\n private readonly _options?: TriggerHandlerMap,\n ) {\n super();\n }\n\n public getActiveTriggers(space: Space): FunctionTrigger[] {\n return this._getTriggers(space, (t) => t.activationCtx != null);\n }\n\n public getInactiveTriggers(space: Space): FunctionTrigger[] {\n return this._getTriggers(space, (t) => t.activationCtx == null);\n }\n\n async activate(triggerCtx: TriggerContext, trigger: FunctionTrigger, callback: TriggerCallback): Promise<void> {\n log('activate', { space: triggerCtx.space.key, trigger });\n const activationCtx = new Context({ name: `trigger_${trigger.function}` });\n this._ctx.onDispose(() => activationCtx.dispose());\n const registeredTrigger = this._triggersBySpaceKey\n .get(triggerCtx.space.key)\n ?.find((reg) => reg.trigger.id === trigger.id);\n invariant(registeredTrigger, `Trigger is not registered: ${trigger.function}`);\n registeredTrigger.activationCtx = activationCtx;\n\n try {\n const options = this._options?.[trigger.spec.type];\n await triggerHandlers[trigger.spec.type](activationCtx, triggerCtx, trigger.spec, callback, options);\n } catch (err) {\n delete registeredTrigger.activationCtx;\n throw err;\n }\n }\n\n /**\n * Loads triggers from the manifest into the space.\n */\n public async register(space: Space, manifest: FunctionManifest): Promise<void> {\n log('register', { space: space.key });\n if (!manifest.triggers?.length) {\n return;\n }\n if (!space.db.graph.runtimeSchemaRegistry.hasSchema(FunctionTrigger)) {\n space.db.graph.runtimeSchemaRegistry.registerSchema(FunctionTrigger);\n }\n\n const reactiveObjects = manifest.triggers.map((template: Omit<FunctionTrigger, 'id'>) =>\n create(FunctionTrigger, { ...template }),\n );\n reactiveObjects.forEach((obj) => space.db.add(obj));\n }\n\n protected override async _open(): Promise<void> {\n const spaceListSubscription = this._client.spaces.subscribe(async (spaces) => {\n for (const space of spaces) {\n if (this._triggersBySpaceKey.has(space.key)) {\n continue;\n }\n\n const registered: RegisteredTrigger[] = [];\n this._triggersBySpaceKey.set(space.key, registered);\n await space.waitUntilReady();\n if (this._ctx.disposed) {\n break;\n }\n const functionsSubscription = space.db.query(Filter.schema(FunctionTrigger)).subscribe(async (triggers) => {\n await this._handleRemovedTriggers(space, triggers.objects, registered);\n this._handleNewTriggers(space, triggers.objects, registered);\n });\n\n this._ctx.onDispose(functionsSubscription);\n }\n });\n\n this._ctx.onDispose(() => spaceListSubscription.unsubscribe());\n }\n\n protected override async _close(_: Context): Promise<void> {\n this._triggersBySpaceKey.clear();\n }\n\n private _handleNewTriggers(space: Space, allTriggers: FunctionTrigger[], registered: RegisteredTrigger[]) {\n const newTriggers = allTriggers.filter((candidate) => {\n return registered.find((reg) => reg.trigger.id === candidate.id) == null;\n });\n\n if (newTriggers.length > 0) {\n const newRegisteredTriggers: RegisteredTrigger[] = newTriggers.map((trigger) => ({ trigger }));\n registered.push(...newRegisteredTriggers);\n log('registered new triggers', () => ({ spaceKey: space.key, functions: newTriggers.map((t) => t.function) }));\n this.registered.emit({ space, triggers: newTriggers });\n }\n }\n\n private async _handleRemovedTriggers(\n space: Space,\n allTriggers: FunctionTrigger[],\n registered: RegisteredTrigger[],\n ): Promise<void> {\n const removed: FunctionTrigger[] = [];\n for (let i = registered.length - 1; i >= 0; i--) {\n const wasRemoved =\n allTriggers.find((trigger: FunctionTrigger) => trigger.id === registered[i].trigger.id) == null;\n if (wasRemoved) {\n const unregistered = registered.splice(i, 1)[0];\n await unregistered.activationCtx?.dispose();\n removed.push(unregistered.trigger);\n }\n }\n\n if (removed.length > 0) {\n this.removed.emit({ space, triggers: removed });\n }\n }\n\n private _getTriggers(space: Space, predicate: (trigger: RegisteredTrigger) => boolean): FunctionTrigger[] {\n const allSpaceTriggers = this._triggersBySpaceKey.get(space.key) ?? [];\n return allSpaceTriggers.filter(predicate).map((trigger) => trigger.trigger);\n }\n}\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { TextV0Type } from '@braneframe/types';\nimport { debounce, DeferredTask } from '@dxos/async';\nimport { type Context } from '@dxos/context';\nimport { createSubscription, Filter, getAutomergeObjectCore, type Query } from '@dxos/echo-db';\nimport { log } from '@dxos/log';\n\nimport type { SubscriptionTrigger } from '../../types';\nimport { type TriggerCallback, type TriggerContext, type TriggerFactory } from '../trigger-registry';\n\nexport const createSubscriptionTrigger: TriggerFactory<SubscriptionTrigger> = async (\n ctx: Context,\n triggerCtx: TriggerContext,\n spec: SubscriptionTrigger,\n callback: TriggerCallback,\n) => {\n const objectIds = new Set<string>();\n const task = new DeferredTask(ctx, async () => {\n if (objectIds.size > 0) {\n await callback({ objects: Array.from(objectIds) });\n objectIds.clear();\n }\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 = triggerCtx.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// Copyright 2024 DXOS.org\n//\n\nimport { CronJob } from 'cron';\n\nimport { DeferredTask } from '@dxos/async';\nimport { type Context } from '@dxos/context';\nimport { log } from '@dxos/log';\n\nimport type { TimerTrigger } from '../../types';\nimport { type TriggerCallback, type TriggerContext, type TriggerFactory } from '../trigger-registry';\n\nexport const createTimerTrigger: TriggerFactory<TimerTrigger> = async (\n ctx: Context,\n triggerContext: TriggerContext,\n spec: TimerTrigger,\n callback: TriggerCallback,\n) => {\n const task = new DeferredTask(ctx, async () => {\n await callback({});\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: triggerContext.space.key.truncate(), count: run, delta });\n task.schedule();\n },\n });\n\n job.start();\n ctx.onDispose(() => job.stop());\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { getPort } from 'get-port-please';\nimport http from 'node:http';\n\nimport { type Context } from '@dxos/context';\nimport { log } from '@dxos/log';\n\nimport type { WebhookTrigger } from '../../types';\nimport { type TriggerCallback, type TriggerContext, type TriggerFactory } from '../trigger-registry';\n\nexport const createWebhookTrigger: TriggerFactory<WebhookTrigger> = async (\n ctx: Context,\n _: TriggerContext,\n spec: WebhookTrigger,\n callback: TriggerCallback,\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 res.statusCode = await callback({});\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// Copyright 2024 DXOS.org\n//\n\nimport WebSocket from 'ws';\n\nimport { sleep, Trigger } from '@dxos/async';\nimport { type Context } from '@dxos/context';\nimport { log } from '@dxos/log';\n\nimport { type WebsocketTrigger } from '../../types';\nimport { type TriggerCallback, type TriggerContext, type TriggerFactory } from '../trigger-registry';\n\ninterface WebsocketTriggerOptions {\n retryDelay: number;\n maxAttempts: number;\n}\n\n/**\n * Websocket.\n * NOTE: The port must be unique, so the same hook cannot be used for multiple spaces.\n */\nexport const createWebsocketTrigger: TriggerFactory<WebsocketTrigger, WebsocketTriggerOptions> = async (\n ctx: Context,\n triggerCtx: TriggerContext,\n spec: WebsocketTrigger,\n callback: TriggerCallback,\n options: WebsocketTriggerOptions = { retryDelay: 2, maxAttempts: 5 },\n) => {\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 createWebsocketTrigger(ctx, triggerCtx, spec, callback, 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 log.info('message');\n const data = JSON.parse(new TextDecoder().decode(event.data as Uint8Array));\n await callback({ 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"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["import_util", "import_async", "import_context", "import_log", "import_node_path", "import_echo", "import_invariant", "import_keys", "import_get_port_please", "subscriptionHandler", "handler", "event", "data", "context", "rest", "client", "space", "spaceKey", "spaces", "get", "PublicKey", "from", "undefined", "objects", "map", "id", "db", "getObjectById", "filter", "nonNullable", "log", "warn", "info", "key", "truncate", "length", "omitEchoId", "schema", "S", "make", "AST", "omit", "ast", "SubscriptionTriggerSchema", "struct", "type", "literal", "array", "string", "props", "optional", "record", "any", "options", "deep", "boolean", "delay", "number", "TimerTriggerSchema", "cron", "WebhookTriggerSchema", "mutable", "method", "port", "WebsocketTriggerSchema", "url", "init", "TriggerSpecSchema", "union", "FunctionDef", "TypedObject", "typename", "version", "uri", "description", "route", "FunctionTrigger", "function", "pipe", "meta", "spec", "FunctionManifestSchema", "functions", "triggers", "FunctionRegistry", "Resource", "constructor", "_client", "_functionBySpaceKey", "ComplexMap", "hash", "onFunctionsRegistered", "Event", "getFunctions", "register", "manifest", "graph", "runtimeSchemaRegistry", "
|
|
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 2024 DXOS.org\n//\n\nimport { Event } from '@dxos/async';\nimport { type Client } from '@dxos/client';\nimport { create, Filter, type Space } from '@dxos/client/echo';\nimport { type Context, Resource } from '@dxos/context';\nimport { PublicKey } from '@dxos/keys';\nimport { ComplexMap } from '@dxos/util';\n\nimport { FunctionDef, type FunctionManifest } from '../types';\n\nexport type FunctionsRegisteredEvent = {\n space: Space;\n newFunctions: FunctionDef[];\n};\n\nexport class FunctionRegistry extends Resource {\n private readonly _functionBySpaceKey = new ComplexMap<PublicKey, FunctionDef[]>(PublicKey.hash);\n\n public readonly onFunctionsRegistered = new Event<FunctionsRegisteredEvent>();\n\n constructor(private readonly _client: Client) {\n super();\n }\n\n public getFunctions(space: Space): FunctionDef[] {\n return this._functionBySpaceKey.get(space.key) ?? [];\n }\n\n /**\n * The method loads function definitions from the manifest into the space.\n * We first load all the definitions from the space to deduplicate by functionId.\n */\n // TODO(burdon): This should not be space specific (they are static for the agent).\n public async register(space: Space, manifest: FunctionManifest): Promise<void> {\n if (!manifest.functions?.length) {\n return;\n }\n if (!space.db.graph.runtimeSchemaRegistry.isSchemaRegistered(FunctionDef)) {\n space.db.graph.runtimeSchemaRegistry.registerSchema(FunctionDef);\n }\n\n const { objects: existingDefinitions } = await space.db.query(Filter.schema(FunctionDef)).run();\n const newDefinitions = getNewDefinitions(manifest.functions, existingDefinitions);\n const reactiveObjects = newDefinitions.map((template) => create(FunctionDef, { ...template }));\n reactiveObjects.forEach((obj) => space.db.add(obj));\n }\n\n protected override async _open(): Promise<void> {\n const spaceListSubscription = this._client.spaces.subscribe(async (spaces) => {\n for (const space of spaces) {\n if (this._functionBySpaceKey.has(space.key)) {\n continue;\n }\n const registered: FunctionDef[] = [];\n this._functionBySpaceKey.set(space.key, registered);\n await space.waitUntilReady();\n if (this._ctx.disposed) {\n break;\n }\n\n const functionsSubscription = space.db.query(Filter.schema(FunctionDef)).subscribe((definitions) => {\n const newFunctions = getNewDefinitions(definitions.objects, registered);\n if (newFunctions.length > 0) {\n registered.push(...newFunctions);\n this.onFunctionsRegistered.emit({ space, newFunctions });\n }\n });\n this._ctx.onDispose(functionsSubscription);\n }\n });\n this._ctx.onDispose(() => spaceListSubscription.unsubscribe());\n }\n\n protected override async _close(_: Context): Promise<void> {\n this._functionBySpaceKey.clear();\n }\n}\n\nconst getNewDefinitions = <T extends { uri: string }>(candidateList: T[], existing: FunctionDef[]): T[] => {\n return candidateList.filter((candidate) => existing.find((def) => def.uri === candidate.uri) == null);\n};\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { AST, S, TypedObject } from '@dxos/echo-schema';\n\n// TODO(burdon): Factor out.\nconst omitEchoId = <T>(schema: S.Schema<T>): S.Schema<Omit<T, 'id'>> => S.make(AST.omit(schema.ast, ['id']));\n\n/**\n * Type discriminator for TriggerSpec.\n * Every spec has a type field of type FunctionTriggerType that we can use to understand which\n * type we're working with.\n * https://www.typescriptlang.org/docs/handbook/2/narrowing.html#discriminated-unions\n */\nexport type FunctionTriggerType = 'subscription' | 'timer' | 'webhook' | 'websocket';\n\nconst SubscriptionTriggerSchema = S.struct({\n type: S.literal('subscription'),\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});\nexport type SubscriptionTrigger = S.Schema.Type<typeof SubscriptionTriggerSchema>;\n\nconst TimerTriggerSchema = S.struct({\n type: S.literal('timer'),\n cron: S.string,\n});\nexport type TimerTrigger = S.Schema.Type<typeof TimerTriggerSchema>;\n\nconst WebhookTriggerSchema = S.mutable(\n S.struct({\n type: S.literal('webhook'),\n method: S.string,\n // Assigned port.\n port: S.optional(S.number),\n }),\n);\nexport type WebhookTrigger = S.Schema.Type<typeof WebhookTriggerSchema>;\n\nconst WebsocketTriggerSchema = S.struct({\n type: S.literal('websocket'),\n url: S.string,\n init: S.optional(S.record(S.string, S.any)),\n});\nexport type WebsocketTrigger = S.Schema.Type<typeof WebsocketTriggerSchema>;\n\nconst TriggerSpecSchema = S.union(\n TimerTriggerSchema,\n WebhookTriggerSchema,\n WebsocketTriggerSchema,\n SubscriptionTriggerSchema,\n);\nexport type TriggerSpec = TimerTrigger | WebhookTrigger | WebsocketTrigger | SubscriptionTrigger;\n\n/**\n * Function definition.\n */\nexport class FunctionDef extends TypedObject({\n typename: 'dxos.org/type/FunctionDef',\n version: '0.1.0',\n})({\n uri: S.string,\n description: S.optional(S.string),\n route: S.string,\n // TODO(burdon): NPM/GitHub/Docker/CF URL?\n handler: S.string,\n}) {}\n\nexport class FunctionTrigger extends TypedObject({\n typename: 'dxos.org/type/FunctionTrigger',\n version: '0.1.0',\n})({\n function: S.string.pipe(S.description('Function ID/URI.')),\n // Context passed to a function.\n meta: S.optional(S.record(S.string, S.any)),\n spec: TriggerSpecSchema,\n}) {}\n\n/**\n * Function manifest file.\n */\nexport const FunctionManifestSchema = S.struct({\n functions: S.optional(S.mutable(S.array(omitEchoId(FunctionDef)))),\n triggers: S.optional(S.mutable(S.array(omitEchoId(FunctionTrigger)))),\n});\n\nexport type FunctionManifest = S.Schema.Type<typeof FunctionManifestSchema>;\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 { Context } from '@dxos/context';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\n\nimport { type FunctionContext, type FunctionEvent, type FunctionHandler, type FunctionResponse } from '../handler';\nimport { type FunctionRegistry } from '../registry';\nimport { type FunctionDef } from '../types';\n\nexport type DevServerOptions = {\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 private _ctx = createContext();\n\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 _functionsRegistry: FunctionRegistry,\n private readonly _options: DevServerOptions,\n ) {\n this._functionsRegistry.onFunctionsRegistered.on(async ({ newFunctions }) => {\n newFunctions.forEach((def) => this._load(def));\n await this._safeUpdateRegistration();\n log('new functions loaded', { newFunctions });\n });\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 start() {\n invariant(!this._server);\n log.info('starting...');\n this._ctx = createContext();\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 });\n\n log.info('registered', { endpoint });\n this._proxy = endpoint;\n this._functionServiceRegistration = registrationId;\n\n // Open after registration, so that it can be updated with the list of function definitions.\n await this._functionsRegistry.open(this._ctx);\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 { uri, route, handler } = def;\n const filePath = join(this._options.baseDir, handler);\n log.info('loading', { uri, 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 // TODO(burdon): Import types.\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: ${uri}`);\n }\n\n this._handlers[route] = { def, handler: module.default };\n }\n\n private async _safeUpdateRegistration(): Promise<void> {\n invariant(this._functionServiceRegistration);\n try {\n await this._client.services.services.FunctionRegistryService!.updateRegistration({\n registrationId: this._functionServiceRegistration,\n functions: this.functions.map(({ def: { id, route } }) => ({ id, route })),\n });\n } catch (e) {\n log.catch(e);\n }\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\nconst createContext = () => new Context({ name: 'DevServer' });\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport path from 'node:path';\n\nimport { type Space } from '@dxos/client/echo';\nimport { Context } from '@dxos/context';\nimport { log } from '@dxos/log';\n\nimport { type FunctionEventMeta } from '../handler';\nimport { type FunctionRegistry } from '../registry';\nimport { type TriggerRegistry } from '../trigger';\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 private _ctx = createContext();\n\n constructor(\n public readonly functions: FunctionRegistry,\n public readonly triggers: TriggerRegistry,\n private readonly _options: SchedulerOptions = {},\n ) {\n this.functions.onFunctionsRegistered.on(async ({ space, newFunctions }) => {\n await this._safeActivateTriggers(space, this.triggers.getInactiveTriggers(space), newFunctions);\n });\n this.triggers.registered.on(async ({ space, triggers }) => {\n await this._safeActivateTriggers(space, triggers, this.functions.getFunctions(space));\n });\n }\n\n async start() {\n await this._ctx.dispose();\n this._ctx = createContext();\n await this.functions.open(this._ctx);\n await this.triggers.open(this._ctx);\n }\n\n async stop() {\n await this._ctx.dispose();\n await this.functions.close();\n await this.triggers.close();\n }\n\n public async register(space: Space, manifest: FunctionManifest) {\n await this.functions.register(space, manifest);\n await this.triggers.register(space, manifest);\n }\n\n private async _safeActivateTriggers(\n space: Space,\n triggers: FunctionTrigger[],\n functions: FunctionDef[],\n ): Promise<void> {\n const mountTasks = triggers.map((trigger) => {\n return this.activate(space, functions, trigger);\n });\n await Promise.all(mountTasks).catch(log.catch);\n }\n\n private async activate(space: Space, functions: FunctionDef[], fnTrigger: FunctionTrigger) {\n const definition = functions.find((def) => def.uri === fnTrigger.function);\n if (!definition) {\n log.info('function is not found for trigger', { fnTrigger });\n return;\n }\n\n await this.triggers.activate({ space }, fnTrigger, async (args) => {\n return this._execFunction(definition, {\n meta: fnTrigger.meta,\n data: { ...args, spaceKey: space.key },\n });\n });\n log('activated trigger', { space: space.key, trigger: fnTrigger });\n }\n\n private async _execFunction<TData, TMeta>(\n def: FunctionDef,\n { data, meta }: { data: TData; meta?: TMeta },\n ): Promise<number> {\n let status = 0;\n try {\n // TODO(burdon): Pass in Space key (common context)?\n const payload = Object.assign({}, meta && ({ meta } 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.route);\n log.info('exec', { function: def.uri, 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.uri });\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.uri, status });\n } catch (err: any) {\n log.error('error', { function: def.uri, error: err.message });\n status = 500;\n }\n\n return status;\n }\n}\n\nconst createContext = () => new Context({ name: 'FunctionScheduler' });\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { Event } from '@dxos/async';\nimport { type Client } from '@dxos/client';\nimport { create, Filter, type Space } from '@dxos/client/echo';\nimport { Context, Resource } from '@dxos/context';\nimport { invariant } from '@dxos/invariant';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { ComplexMap } from '@dxos/util';\n\nimport { createSubscriptionTrigger, createTimerTrigger, createWebhookTrigger, createWebsocketTrigger } from './type';\nimport { type FunctionManifest, FunctionTrigger, type FunctionTriggerType, type TriggerSpec } from '../types';\n\ntype ResponseCode = number;\n\nexport type TriggerCallback = (args: object) => Promise<ResponseCode>;\n\nexport type TriggerContext = { space: Space };\n\n// TODO(burdon): Make object?\nexport type TriggerFactory<Spec extends TriggerSpec, Options = any> = (\n ctx: Context,\n context: TriggerContext,\n spec: Spec,\n callback: TriggerCallback,\n options?: Options,\n) => Promise<void>;\n\nexport type TriggerHandlerMap = { [type in FunctionTriggerType]: TriggerFactory<any> };\n\nconst triggerHandlers: TriggerHandlerMap = {\n subscription: createSubscriptionTrigger,\n timer: createTimerTrigger,\n webhook: createWebhookTrigger,\n websocket: createWebsocketTrigger,\n};\n\nexport type TriggerEvent = {\n space: Space;\n triggers: FunctionTrigger[];\n};\n\ntype RegisteredTrigger = {\n activationCtx?: Context;\n trigger: FunctionTrigger;\n};\n\nexport class TriggerRegistry extends Resource {\n private readonly _triggersBySpaceKey = new ComplexMap<PublicKey, RegisteredTrigger[]>(PublicKey.hash);\n\n public readonly registered = new Event<TriggerEvent>();\n public readonly removed = new Event<TriggerEvent>();\n\n constructor(\n private readonly _client: Client,\n private readonly _options?: TriggerHandlerMap,\n ) {\n super();\n }\n\n public getActiveTriggers(space: Space): FunctionTrigger[] {\n return this._getTriggers(space, (t) => t.activationCtx != null);\n }\n\n public getInactiveTriggers(space: Space): FunctionTrigger[] {\n return this._getTriggers(space, (t) => t.activationCtx == null);\n }\n\n async activate(triggerCtx: TriggerContext, trigger: FunctionTrigger, callback: TriggerCallback): Promise<void> {\n log('activate', { space: triggerCtx.space.key, trigger });\n const activationCtx = new Context({ name: `trigger_${trigger.function}` });\n this._ctx.onDispose(() => activationCtx.dispose());\n const registeredTrigger = this._triggersBySpaceKey\n .get(triggerCtx.space.key)\n ?.find((reg) => reg.trigger.id === trigger.id);\n invariant(registeredTrigger, `Trigger is not registered: ${trigger.function}`);\n registeredTrigger.activationCtx = activationCtx;\n\n try {\n const options = this._options?.[trigger.spec.type];\n await triggerHandlers[trigger.spec.type](activationCtx, triggerCtx, trigger.spec, callback, options);\n } catch (err) {\n delete registeredTrigger.activationCtx;\n throw err;\n }\n }\n\n /**\n * Loads triggers from the manifest into the space.\n */\n public async register(space: Space, manifest: FunctionManifest): Promise<void> {\n log('register', { space: space.key });\n if (!manifest.triggers?.length) {\n return;\n }\n if (!space.db.graph.runtimeSchemaRegistry.isSchemaRegistered(FunctionTrigger)) {\n space.db.graph.runtimeSchemaRegistry.registerSchema(FunctionTrigger);\n }\n\n const reactiveObjects = manifest.triggers.map((template: Omit<FunctionTrigger, 'id'>) =>\n create(FunctionTrigger, { ...template }),\n );\n reactiveObjects.forEach((obj) => space.db.add(obj));\n }\n\n protected override async _open(): Promise<void> {\n const spaceListSubscription = this._client.spaces.subscribe(async (spaces) => {\n for (const space of spaces) {\n if (this._triggersBySpaceKey.has(space.key)) {\n continue;\n }\n\n const registered: RegisteredTrigger[] = [];\n this._triggersBySpaceKey.set(space.key, registered);\n await space.waitUntilReady();\n if (this._ctx.disposed) {\n break;\n }\n const functionsSubscription = space.db.query(Filter.schema(FunctionTrigger)).subscribe(async (triggers) => {\n await this._handleRemovedTriggers(space, triggers.objects, registered);\n this._handleNewTriggers(space, triggers.objects, registered);\n });\n\n this._ctx.onDispose(functionsSubscription);\n }\n });\n\n this._ctx.onDispose(() => spaceListSubscription.unsubscribe());\n }\n\n protected override async _close(_: Context): Promise<void> {\n this._triggersBySpaceKey.clear();\n }\n\n private _handleNewTriggers(space: Space, allTriggers: FunctionTrigger[], registered: RegisteredTrigger[]) {\n const newTriggers = allTriggers.filter((candidate) => {\n return registered.find((reg) => reg.trigger.id === candidate.id) == null;\n });\n\n if (newTriggers.length > 0) {\n const newRegisteredTriggers: RegisteredTrigger[] = newTriggers.map((trigger) => ({ trigger }));\n registered.push(...newRegisteredTriggers);\n log('registered new triggers', () => ({ spaceKey: space.key, functions: newTriggers.map((t) => t.function) }));\n this.registered.emit({ space, triggers: newTriggers });\n }\n }\n\n private async _handleRemovedTriggers(\n space: Space,\n allTriggers: FunctionTrigger[],\n registered: RegisteredTrigger[],\n ): Promise<void> {\n const removed: FunctionTrigger[] = [];\n for (let i = registered.length - 1; i >= 0; i--) {\n const wasRemoved =\n allTriggers.find((trigger: FunctionTrigger) => trigger.id === registered[i].trigger.id) == null;\n if (wasRemoved) {\n const unregistered = registered.splice(i, 1)[0];\n await unregistered.activationCtx?.dispose();\n removed.push(unregistered.trigger);\n }\n }\n\n if (removed.length > 0) {\n this.removed.emit({ space, triggers: removed });\n }\n }\n\n private _getTriggers(space: Space, predicate: (trigger: RegisteredTrigger) => boolean): FunctionTrigger[] {\n const allSpaceTriggers = this._triggersBySpaceKey.get(space.key) ?? [];\n return allSpaceTriggers.filter(predicate).map((trigger) => trigger.trigger);\n }\n}\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { TextV0Type } from '@braneframe/types';\nimport { debounce, DeferredTask } from '@dxos/async';\nimport { type Context } from '@dxos/context';\nimport { createSubscription, Filter, getAutomergeObjectCore, type Query } from '@dxos/echo-db';\nimport { log } from '@dxos/log';\n\nimport type { SubscriptionTrigger } from '../../types';\nimport { type TriggerCallback, type TriggerContext, type TriggerFactory } from '../trigger-registry';\n\nexport const createSubscriptionTrigger: TriggerFactory<SubscriptionTrigger> = async (\n ctx: Context,\n triggerCtx: TriggerContext,\n spec: SubscriptionTrigger,\n callback: TriggerCallback,\n) => {\n const objectIds = new Set<string>();\n const task = new DeferredTask(ctx, async () => {\n if (objectIds.size > 0) {\n await callback({ objects: Array.from(objectIds) });\n objectIds.clear();\n }\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 = triggerCtx.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// Copyright 2024 DXOS.org\n//\n\nimport { CronJob } from 'cron';\n\nimport { DeferredTask } from '@dxos/async';\nimport { type Context } from '@dxos/context';\nimport { log } from '@dxos/log';\n\nimport type { TimerTrigger } from '../../types';\nimport { type TriggerCallback, type TriggerContext, type TriggerFactory } from '../trigger-registry';\n\nexport const createTimerTrigger: TriggerFactory<TimerTrigger> = async (\n ctx: Context,\n triggerContext: TriggerContext,\n spec: TimerTrigger,\n callback: TriggerCallback,\n) => {\n const task = new DeferredTask(ctx, async () => {\n await callback({});\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: triggerContext.space.key.truncate(), count: run, delta });\n task.schedule();\n },\n });\n\n job.start();\n ctx.onDispose(() => job.stop());\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { getPort } from 'get-port-please';\nimport http from 'node:http';\n\nimport { type Context } from '@dxos/context';\nimport { log } from '@dxos/log';\n\nimport type { WebhookTrigger } from '../../types';\nimport { type TriggerCallback, type TriggerContext, type TriggerFactory } from '../trigger-registry';\n\nexport const createWebhookTrigger: TriggerFactory<WebhookTrigger> = async (\n ctx: Context,\n _: TriggerContext,\n spec: WebhookTrigger,\n callback: TriggerCallback,\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 res.statusCode = await callback({});\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// Copyright 2024 DXOS.org\n//\n\nimport WebSocket from 'ws';\n\nimport { sleep, Trigger } from '@dxos/async';\nimport { type Context } from '@dxos/context';\nimport { log } from '@dxos/log';\n\nimport { type WebsocketTrigger } from '../../types';\nimport { type TriggerCallback, type TriggerContext, type TriggerFactory } from '../trigger-registry';\n\ninterface WebsocketTriggerOptions {\n retryDelay: number;\n maxAttempts: number;\n}\n\n/**\n * Websocket.\n * NOTE: The port must be unique, so the same hook cannot be used for multiple spaces.\n */\nexport const createWebsocketTrigger: TriggerFactory<WebsocketTrigger, WebsocketTriggerOptions> = async (\n ctx: Context,\n triggerCtx: TriggerContext,\n spec: WebsocketTrigger,\n callback: TriggerCallback,\n options: WebsocketTriggerOptions = { retryDelay: 2, maxAttempts: 5 },\n) => {\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 createWebsocketTrigger(ctx, triggerCtx, spec, callback, 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 log.info('message');\n const data = JSON.parse(new TextDecoder().decode(event.data as Uint8Array));\n await callback({ 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"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["import_util", "import_async", "import_context", "import_log", "import_node_path", "import_echo", "import_invariant", "import_keys", "import_get_port_please", "subscriptionHandler", "handler", "event", "data", "context", "rest", "client", "space", "spaceKey", "spaces", "get", "PublicKey", "from", "undefined", "objects", "map", "id", "db", "getObjectById", "filter", "nonNullable", "log", "warn", "info", "key", "truncate", "length", "omitEchoId", "schema", "S", "make", "AST", "omit", "ast", "SubscriptionTriggerSchema", "struct", "type", "literal", "array", "string", "props", "optional", "record", "any", "options", "deep", "boolean", "delay", "number", "TimerTriggerSchema", "cron", "WebhookTriggerSchema", "mutable", "method", "port", "WebsocketTriggerSchema", "url", "init", "TriggerSpecSchema", "union", "FunctionDef", "TypedObject", "typename", "version", "uri", "description", "route", "FunctionTrigger", "function", "pipe", "meta", "spec", "FunctionManifestSchema", "functions", "triggers", "FunctionRegistry", "Resource", "constructor", "_client", "_functionBySpaceKey", "ComplexMap", "hash", "onFunctionsRegistered", "Event", "getFunctions", "register", "manifest", "graph", "runtimeSchemaRegistry", "isSchemaRegistered", "registerSchema", "existingDefinitions", "query", "Filter", "run", "newDefinitions", "getNewDefinitions", "reactiveObjects", "template", "create", "forEach", "obj", "add", "_open", "spaceListSubscription", "subscribe", "has", "registered", "set", "waitUntilReady", "_ctx", "disposed", "functionsSubscription", "definitions", "newFunctions", "push", "emit", "onDispose", "unsubscribe", "_close", "_", "clear", "candidateList", "existing", "candidate", "find", "def", "DevServer", "_functionsRegistry", "_options", "createContext", "_handlers", "_seq", "update", "on", "_load", "_safeUpdateRegistration", "stats", "seq", "endpoint", "invariant", "_port", "proxy", "_proxy", "Object", "values", "start", "_server", "app", "express", "use", "json", "post", "req", "res", "path", "params", "reload", "statusCode", "invoke", "body", "end", "err", "catch", "getPort", "host", "portRange", "listen", "registrationId", "services", "FunctionRegistryService", "_functionServiceRegistration", "open", "stop", "Error", "trigger", "Trigger", "close", "unregister", "wake", "throw", "wait", "force", "filePath", "join", "baseDir", "keys", "require", "cache", "startsWith", "module", "default", "updateRegistration", "e", "now", "Date", "_invoke", "duration", "dataDir", "response", "status", "code", "Context", "name", "Scheduler", "_safeActivateTriggers", "getInactiveTriggers", "dispose", "mountTasks", "activate", "Promise", "all", "fnTrigger", "definition", "args", "_execFunction", "payload", "assign", "callback", "fetch", "headers", "JSON", "stringify", "error", "message", "createSubscriptionTrigger", "ctx", "triggerCtx", "objectIds", "Set", "task", "DeferredTask", "size", "Array", "subscriptions", "subscription", "createSubscription", "added", "updated", "object", "schedule", "content", "TextV0Type", "getAutomergeObjectCore", "updates", "debounce", "or", "createTimerTrigger", "triggerContext", "last", "job", "CronJob", "cronTime", "runOnInit", "onTick", "delta", "count", "createWebhookTrigger", "server", "http", "createServer", "random", "createWebsocketTrigger", "retryDelay", "maxAttempts", "ws", "attempt", "WebSocket", "onopen", "send", "TextEncoder", "encode", "onclose", "setTimeout", "onerror", "onmessage", "parse", "TextDecoder", "decode", "isOpen", "Math", "pow", "sleep", "triggerHandlers", "timer", "webhook", "websocket", "TriggerRegistry", "_triggersBySpaceKey", "removed", "getActiveTriggers", "_getTriggers", "t", "activationCtx", "registeredTrigger", "reg", "_handleRemovedTriggers", "_handleNewTriggers", "allTriggers", "newTriggers", "newRegisteredTriggers", "i", "wasRemoved", "unregistered", "splice", "predicate", "allSpaceTriggers"]
|
|
7
7
|
}
|
package/dist/lib/node/meta.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"inputs":{"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}],"format":"esm"},"packages/core/functions/src/types.ts":{"bytes":9313,"imports":[{"path":"@dxos/echo-schema","kind":"import-statement","external":true}],"format":"esm"},"packages/core/functions/src/registry/function-registry.ts":{"bytes":
|
|
1
|
+
{"inputs":{"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}],"format":"esm"},"packages/core/functions/src/types.ts":{"bytes":9313,"imports":[{"path":"@dxos/echo-schema","kind":"import-statement","external":true}],"format":"esm"},"packages/core/functions/src/registry/function-registry.ts":{"bytes":11292,"imports":[{"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/keys","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"packages/core/functions/src/types.ts","kind":"import-statement","original":"../types"}],"format":"esm"},"packages/core/functions/src/registry/index.ts":{"bytes":497,"imports":[{"path":"packages/core/functions/src/registry/function-registry.ts","kind":"import-statement","original":"./function-registry"}],"format":"esm"},"packages/core/functions/src/runtime/dev-server.ts":{"bytes":27510,"imports":[{"path":"express","kind":"import-statement","external":true},{"path":"get-port-please","kind":"import-statement","external":true},{"path":"node:path","kind":"import-statement","external":true},{"path":"@dxos/async","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":"<runtime>","kind":"import-statement","external":true}],"format":"esm"},"packages/core/functions/src/runtime/scheduler.ts":{"bytes":15341,"imports":[{"path":"node:path","kind":"import-statement","external":true},{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/log","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"}],"format":"esm"},"packages/core/functions/src/trigger/type/subscription-trigger.ts":{"bytes":9356,"imports":[{"path":"@braneframe/types","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/echo-db","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true}],"format":"esm"},"packages/core/functions/src/trigger/type/timer-trigger.ts":{"bytes":4169,"imports":[{"path":"cron","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true}],"format":"esm"},"packages/core/functions/src/trigger/type/webhook-trigger.ts":{"bytes":4272,"imports":[{"path":"get-port-please","kind":"import-statement","external":true},{"path":"node:http","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true}],"format":"esm"},"packages/core/functions/src/trigger/type/websocket-trigger.ts":{"bytes":10377,"imports":[{"path":"ws","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true}],"format":"esm"},"packages/core/functions/src/trigger/type/index.ts":{"bytes":829,"imports":[{"path":"packages/core/functions/src/trigger/type/subscription-trigger.ts","kind":"import-statement","original":"./subscription-trigger"},{"path":"packages/core/functions/src/trigger/type/timer-trigger.ts","kind":"import-statement","original":"./timer-trigger"},{"path":"packages/core/functions/src/trigger/type/webhook-trigger.ts","kind":"import-statement","original":"./webhook-trigger"},{"path":"packages/core/functions/src/trigger/type/websocket-trigger.ts","kind":"import-statement","original":"./websocket-trigger"}],"format":"esm"},"packages/core/functions/src/trigger/trigger-registry.ts":{"bytes":21856,"imports":[{"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/keys","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"packages/core/functions/src/trigger/type/index.ts","kind":"import-statement","original":"./type"},{"path":"packages/core/functions/src/types.ts","kind":"import-statement","original":"../types"}],"format":"esm"},"packages/core/functions/src/trigger/index.ts":{"bytes":495,"imports":[{"path":"packages/core/functions/src/trigger/trigger-registry.ts","kind":"import-statement","original":"./trigger-registry"}],"format":"esm"},"packages/core/functions/src/index.ts":{"bytes":801,"imports":[{"path":"packages/core/functions/src/handler.ts","kind":"import-statement","original":"./handler"},{"path":"packages/core/functions/src/registry/index.ts","kind":"import-statement","original":"./registry"},{"path":"packages/core/functions/src/runtime/index.ts","kind":"import-statement","original":"./runtime"},{"path":"packages/core/functions/src/trigger/index.ts","kind":"import-statement","original":"./trigger"},{"path":"packages/core/functions/src/types.ts","kind":"import-statement","original":"./types"}],"format":"esm"}},"outputs":{"packages/core/functions/dist/lib/node/index.cjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":59058},"packages/core/functions/dist/lib/node/index.cjs":{"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":"@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/keys","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"@dxos/echo-schema","kind":"import-statement","external":true},{"path":"express","kind":"import-statement","external":true},{"path":"get-port-please","kind":"import-statement","external":true},{"path":"node:path","kind":"import-statement","external":true},{"path":"@dxos/async","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":"node:path","kind":"import-statement","external":true},{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/log","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/keys","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"@braneframe/types","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/echo-db","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"cron","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"get-port-please","kind":"import-statement","external":true},{"path":"node:http","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"ws","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true}],"exports":["DevServer","FunctionDef","FunctionManifestSchema","FunctionRegistry","FunctionTrigger","Scheduler","TriggerRegistry","subscriptionHandler"],"entryPoint":"packages/core/functions/src/index.ts","inputs":{"packages/core/functions/src/handler.ts":{"bytesInOutput":1124},"packages/core/functions/src/index.ts":{"bytesInOutput":0},"packages/core/functions/src/registry/function-registry.ts":{"bytesInOutput":2605},"packages/core/functions/src/types.ts":{"bytesInOutput":1789},"packages/core/functions/src/registry/index.ts":{"bytesInOutput":0},"packages/core/functions/src/runtime/dev-server.ts":{"bytesInOutput":7819},"packages/core/functions/src/runtime/index.ts":{"bytesInOutput":0},"packages/core/functions/src/runtime/scheduler.ts":{"bytesInOutput":3827},"packages/core/functions/src/trigger/trigger-registry.ts":{"bytesInOutput":5266},"packages/core/functions/src/trigger/type/subscription-trigger.ts":{"bytesInOutput":2083},"packages/core/functions/src/trigger/type/index.ts":{"bytesInOutput":0},"packages/core/functions/src/trigger/type/timer-trigger.ts":{"bytesInOutput":940},"packages/core/functions/src/trigger/type/webhook-trigger.ts":{"bytesInOutput":825},"packages/core/functions/src/trigger/type/websocket-trigger.ts":{"bytesInOutput":2847},"packages/core/functions/src/trigger/index.ts":{"bytesInOutput":0}},"bytes":30384}}}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/functions",
|
|
3
|
-
"version": "0.5.3-main.
|
|
3
|
+
"version": "0.5.3-main.d7fe7b5",
|
|
4
4
|
"description": "Functions SDK and runtime.",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -26,23 +26,23 @@
|
|
|
26
26
|
"express": "^4.19.2",
|
|
27
27
|
"get-port-please": "^3.1.1",
|
|
28
28
|
"ws": "^8.14.2",
|
|
29
|
-
"@braneframe/types": "0.5.3-main.
|
|
30
|
-
"@dxos/async": "0.5.3-main.
|
|
31
|
-
"@dxos/
|
|
32
|
-
"@dxos/
|
|
33
|
-
"@dxos/echo-db": "0.5.3-main.
|
|
34
|
-
"@dxos/invariant": "0.5.3-main.
|
|
35
|
-
"@dxos/
|
|
36
|
-
"@dxos/
|
|
37
|
-
"@dxos/log": "0.5.3-main.
|
|
38
|
-
"@dxos/node-std": "0.5.3-main.
|
|
39
|
-
"@dxos/util": "0.5.3-main.
|
|
40
|
-
"@dxos/protocols": "0.5.3-main.
|
|
29
|
+
"@braneframe/types": "0.5.3-main.d7fe7b5",
|
|
30
|
+
"@dxos/async": "0.5.3-main.d7fe7b5",
|
|
31
|
+
"@dxos/context": "0.5.3-main.d7fe7b5",
|
|
32
|
+
"@dxos/client": "0.5.3-main.d7fe7b5",
|
|
33
|
+
"@dxos/echo-db": "0.5.3-main.d7fe7b5",
|
|
34
|
+
"@dxos/invariant": "0.5.3-main.d7fe7b5",
|
|
35
|
+
"@dxos/keys": "0.5.3-main.d7fe7b5",
|
|
36
|
+
"@dxos/echo-schema": "0.5.3-main.d7fe7b5",
|
|
37
|
+
"@dxos/log": "0.5.3-main.d7fe7b5",
|
|
38
|
+
"@dxos/node-std": "0.5.3-main.d7fe7b5",
|
|
39
|
+
"@dxos/util": "0.5.3-main.d7fe7b5",
|
|
40
|
+
"@dxos/protocols": "0.5.3-main.d7fe7b5"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@types/express": "^4.17.17",
|
|
44
44
|
"@types/ws": "^7.4.0",
|
|
45
|
-
"@dxos/agent": "0.5.3-main.
|
|
45
|
+
"@dxos/agent": "0.5.3-main.d7fe7b5"
|
|
46
46
|
},
|
|
47
47
|
"publishConfig": {
|
|
48
48
|
"access": "public"
|
|
@@ -38,7 +38,7 @@ export class FunctionRegistry extends Resource {
|
|
|
38
38
|
if (!manifest.functions?.length) {
|
|
39
39
|
return;
|
|
40
40
|
}
|
|
41
|
-
if (!space.db.graph.runtimeSchemaRegistry.
|
|
41
|
+
if (!space.db.graph.runtimeSchemaRegistry.isSchemaRegistered(FunctionDef)) {
|
|
42
42
|
space.db.graph.runtimeSchemaRegistry.registerSchema(FunctionDef);
|
|
43
43
|
}
|
|
44
44
|
|
|
@@ -96,7 +96,7 @@ export class TriggerRegistry extends Resource {
|
|
|
96
96
|
if (!manifest.triggers?.length) {
|
|
97
97
|
return;
|
|
98
98
|
}
|
|
99
|
-
if (!space.db.graph.runtimeSchemaRegistry.
|
|
99
|
+
if (!space.db.graph.runtimeSchemaRegistry.isSchemaRegistered(FunctionTrigger)) {
|
|
100
100
|
space.db.graph.runtimeSchemaRegistry.registerSchema(FunctionTrigger);
|
|
101
101
|
}
|
|
102
102
|
|