every-plugin 3.0.0-rc.0 → 3.0.0-rc.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client.cjs +69 -0
- package/dist/client.cjs.map +1 -0
- package/dist/client.d.cts +15 -0
- package/dist/client.d.cts.map +1 -0
- package/dist/client.d.mts +15 -0
- package/dist/client.d.mts.map +1 -0
- package/dist/client.mjs +68 -0
- package/dist/client.mjs.map +1 -0
- package/dist/dev/host.cjs +149 -0
- package/dist/dev/host.cjs.map +1 -0
- package/dist/dev/host.d.cts +32 -0
- package/dist/dev/host.d.cts.map +1 -0
- package/dist/dev/host.d.mts +32 -0
- package/dist/dev/host.d.mts.map +1 -0
- package/dist/dev/host.mjs +148 -0
- package/dist/dev/host.mjs.map +1 -0
- package/dist/dev/serve.cjs +14 -109
- package/dist/dev/serve.cjs.map +1 -1
- package/dist/dev/serve.d.cts.map +1 -1
- package/dist/dev/serve.d.mts.map +1 -1
- package/dist/dev/serve.mjs +14 -109
- package/dist/dev/serve.mjs.map +1 -1
- package/dist/errors.cjs +1 -0
- package/dist/errors.cjs.map +1 -1
- package/dist/errors.d.cts +2 -2
- package/dist/errors.d.mts +2 -2
- package/dist/errors.mjs +2 -2
- package/dist/errors.mjs.map +1 -1
- package/dist/index.cjs +3 -0
- package/dist/index.d.cts +5 -4
- package/dist/index.d.mts +5 -4
- package/dist/index.mjs +3 -2
- package/dist/plugin.cjs +1 -0
- package/dist/plugin.cjs.map +1 -1
- package/dist/plugin.d.cts +17 -3
- package/dist/plugin.d.cts.map +1 -1
- package/dist/plugin.d.mts +16 -2
- package/dist/plugin.d.mts.map +1 -1
- package/dist/plugin.mjs +1 -0
- package/dist/plugin.mjs.map +1 -1
- package/dist/runtime/errors.cjs +20 -0
- package/dist/runtime/errors.cjs.map +1 -1
- package/dist/runtime/errors.d.cts +23 -1
- package/dist/runtime/errors.d.cts.map +1 -1
- package/dist/runtime/errors.d.mts +23 -1
- package/dist/runtime/errors.d.mts.map +1 -1
- package/dist/runtime/errors.mjs +20 -1
- package/dist/runtime/errors.mjs.map +1 -1
- package/dist/runtime/mf-config.cjs +1 -1
- package/dist/runtime/mf-config.mjs +1 -1
- package/dist/runtime/services/module-federation.service.cjs +1 -7
- package/dist/runtime/services/module-federation.service.cjs.map +1 -1
- package/dist/runtime/services/module-federation.service.mjs +1 -7
- package/dist/runtime/services/module-federation.service.mjs.map +1 -1
- package/dist/runtime/services/plugin-loader.service.cjs +26 -1
- package/dist/runtime/services/plugin-loader.service.cjs.map +1 -1
- package/dist/runtime/services/plugin-loader.service.d.cts +2 -2
- package/dist/runtime/services/plugin-loader.service.mjs +26 -1
- package/dist/runtime/services/plugin-loader.service.mjs.map +1 -1
- package/dist/runtime/services/shared-identity.cjs +1 -1
- package/dist/runtime/services/shared-identity.cjs.map +1 -1
- package/dist/runtime/services/shared-identity.mjs +1 -1
- package/dist/runtime/services/shared-identity.mjs.map +1 -1
- package/dist/types.d.cts +26 -2
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts +25 -1
- package/dist/types.d.mts.map +1 -1
- package/dist/version-manifest.cjs +1 -1
- package/dist/version-manifest.cjs.map +1 -1
- package/dist/version-manifest.mjs +1 -1
- package/dist/version-manifest.mjs.map +1 -1
- package/package.json +19 -2
- package/src/client.ts +111 -0
- package/src/dev/host.ts +235 -0
- package/src/dev/serve.ts +14 -135
- package/src/errors.ts +2 -1
- package/src/index.ts +9 -0
- package/src/plugin.ts +20 -1
- package/src/runtime/errors.ts +44 -0
- package/src/runtime/services/module-federation.service.ts +4 -7
- package/src/runtime/services/plugin-loader.service.ts +32 -0
- package/src/runtime/services/shared-identity.ts +1 -1
- package/src/types.ts +39 -2
- package/src/version-manifest.ts +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin-loader.service.mjs","names":[],"sources":["../../../src/runtime/services/plugin-loader.service.ts"],"sourcesContent":["import type { InferSchemaInput, InferSchemaOutput } from \"@orpc/contract\";\nimport { Context, Effect, Exit, Layer, Scope } from \"effect\";\nimport type { z } from \"zod\";\nimport { PluginIdTag } from \"../../plugin\";\nimport type {\n AnyPlugin,\n AnyPluginConstructor,\n InitializedPlugin,\n LoadedPlugin,\n PluginInstance,\n PluginMetadata,\n PluginRegistry,\n} from \"../../types\";\nimport { PluginRuntimeError, toPluginRuntimeError } from \"../errors\";\nimport { validate } from \"../validation\";\nimport { ModuleFederationService } from \"./module-federation.service\";\nimport { SecretsService } from \"./secrets.service\";\n\nexport class PluginRegistryTag extends Context.Service<PluginRegistryTag, PluginRegistry>()(\n \"PluginRegistry\",\n) {}\n\nexport class PluginMapTag extends Context.Service<\n PluginMapTag,\n Record<string, AnyPluginConstructor>\n>()(\"PluginMap\") {}\n\nexport interface RegistryServiceShape {\n get: (\n pluginId: string,\n ) => Effect.Effect<\n { constructor: (new () => AnyPlugin) | null; metadata: PluginMetadata },\n PluginRuntimeError\n >;\n getModule: (pluginId: string) => Effect.Effect<AnyPluginConstructor | null>;\n}\n\nexport class RegistryService extends Context.Service<RegistryService, RegistryServiceShape>()(\n \"RegistryService\",\n) {}\n\nexport const RegistryServiceDefault = Layer.effect(\n RegistryService,\n Effect.gen(function* () {\n const registry = yield* PluginRegistryTag;\n const pluginMap = yield* PluginMapTag;\n\n return {\n get: (pluginId: string) =>\n Effect.gen(function* () {\n const entry = registry[pluginId];\n\n if (!entry) {\n return yield* new PluginRuntimeError({\n pluginId,\n operation: \"validate-plugin-id\",\n cause: new Error(`Plugin ${pluginId} not found in registry`),\n });\n }\n\n if (\"module\" in entry) {\n return {\n constructor: entry.module,\n metadata: {\n remoteUrl: entry.remote || \"\",\n version: entry.version,\n description: entry.description,\n } as PluginMetadata,\n };\n }\n\n return {\n constructor: null,\n metadata: {\n remoteUrl: entry.remote,\n version: entry.version,\n description: entry.description,\n } as PluginMetadata,\n };\n }),\n\n getModule: (pluginId: string) => Effect.succeed(pluginMap[pluginId] || null),\n };\n }),\n);\n\nexport interface PluginLoaderServiceShape {\n loadPlugin: (pluginId: string) => Effect.Effect<LoadedPlugin, PluginRuntimeError>;\n instantiatePlugin: <T extends AnyPlugin>(\n pluginId: string,\n loadedPlugin: LoadedPlugin<T>,\n ) => Effect.Effect<PluginInstance<T>, PluginRuntimeError>;\n initializePlugin: <T extends AnyPlugin>(\n pluginInstance: PluginInstance<T>,\n config: {\n variables: InferSchemaInput<T[\"configSchema\"][\"variables\"]>;\n secrets: InferSchemaInput<T[\"configSchema\"][\"secrets\"]>;\n },\n plugins?: Record<string, unknown>,\n ) => Effect.Effect<InitializedPlugin<T>, PluginRuntimeError>;\n}\n\nexport class PluginLoaderService extends Context.Service<\n PluginLoaderService,\n PluginLoaderServiceShape\n>()(\"PluginLoaderService\") {}\n\nexport const PluginLoaderServiceDefault = Layer.effect(\n PluginLoaderService,\n Effect.gen(function* () {\n const moduleFederationService = yield* ModuleFederationService;\n const secretsService = yield* SecretsService;\n const registryService = yield* RegistryService;\n\n const resolveUrl = (baseUrl: string, version?: string): string =>\n version && version !== \"latest\" ? baseUrl.replace(\"@latest\", `@${version}`) : baseUrl;\n\n return {\n loadPlugin: (pluginId: string) =>\n Effect.gen(function* () {\n const entry = yield* registryService.get(pluginId);\n\n if (entry.constructor) {\n yield* Effect.logDebug(\"Loading plugin from direct module\", { pluginId });\n\n return {\n ctor: entry.constructor,\n metadata: entry.metadata,\n } satisfies LoadedPlugin;\n }\n\n const url = entry.metadata.remoteUrl;\n if (!url) {\n return yield* new PluginRuntimeError({\n pluginId,\n operation: \"load-plugin\",\n cause: new Error(`Plugin ${pluginId} has no module or remote URL configured`),\n });\n }\n\n const resolvedUrl = resolveUrl(url);\n\n yield* moduleFederationService.registerRemote(pluginId, resolvedUrl).pipe(\n Effect.tapError((error) =>\n Effect.logError(`Plugin ${pluginId} failed during register-remote: ${String(error)}`),\n ),\n Effect.mapError((error) =>\n toPluginRuntimeError(error, pluginId, undefined, \"register-remote\"),\n ),\n );\n\n yield* Effect.logDebug(\"Loading plugin from remote\", { pluginId, url: resolvedUrl });\n\n const ctor = yield* moduleFederationService\n .loadRemoteConstructor(pluginId, resolvedUrl)\n .pipe(\n Effect.tapError((error) =>\n Effect.logError(`Plugin ${pluginId} failed during load-remote: ${String(error)}`),\n ),\n Effect.mapError((error) =>\n toPluginRuntimeError(error, pluginId, undefined, \"load-remote\"),\n ),\n );\n\n return {\n ctor,\n metadata: entry.metadata,\n } satisfies LoadedPlugin;\n }),\n\n instantiatePlugin: <T extends AnyPlugin>(pluginId: string, loadedPlugin: LoadedPlugin<T>) =>\n Effect.gen(function* () {\n const instance = yield* Effect.try(() => new loadedPlugin.ctor()).pipe(\n Effect.tapError((error) =>\n Effect.logError(`Plugin ${pluginId} failed during instantiate-plugin: ${error}`),\n ),\n Effect.mapError((error) =>\n toPluginRuntimeError(error, pluginId, undefined, \"instantiate-plugin\"),\n ),\n );\n\n (instance.id as string) = pluginId;\n\n return {\n plugin: instance,\n metadata: loadedPlugin.metadata,\n } satisfies PluginInstance<T>;\n }),\n\n initializePlugin: <T extends AnyPlugin>(\n pluginInstance: PluginInstance<T>,\n config: {\n variables: InferSchemaInput<T[\"configSchema\"][\"variables\"]>;\n secrets: InferSchemaInput<T[\"configSchema\"][\"secrets\"]>;\n },\n plugins?: Record<string, unknown>,\n ) =>\n Effect.gen(function* () {\n const { plugin } = pluginInstance;\n\n // Validate and hydrate config\n const validatedVariables = yield* validate(\n plugin.configSchema.variables as z.ZodSchema<\n InferSchemaOutput<T[\"configSchema\"][\"variables\"]>\n >,\n config.variables,\n plugin.id,\n \"config\",\n ).pipe(\n Effect.mapError(\n (validationError) =>\n new PluginRuntimeError({\n pluginId: plugin.id,\n operation: \"validate-config\",\n cause: validationError.zodError,\n }),\n ),\n );\n\n // Validate secrets\n const validatedSecrets = yield* validate(\n plugin.configSchema.secrets as z.ZodSchema<\n InferSchemaOutput<T[\"configSchema\"][\"secrets\"]>\n >,\n config.secrets,\n plugin.id,\n \"config\",\n ).pipe(\n Effect.mapError(\n (validationError) =>\n new PluginRuntimeError({\n pluginId: plugin.id,\n operation: \"validate-secrets\",\n cause: validationError.zodError,\n }),\n ),\n );\n\n // Hydrate secrets in variables\n const hydratedConfig = yield* secretsService.hydrateSecrets({\n variables: validatedVariables,\n secrets: validatedSecrets,\n });\n\n const _variables = yield* validate(\n plugin.configSchema.variables as z.ZodSchema<\n InferSchemaOutput<T[\"configSchema\"][\"variables\"]>\n >,\n hydratedConfig.variables,\n plugin.id,\n \"config\",\n ).pipe(\n Effect.mapError(\n (validationError) =>\n new PluginRuntimeError({\n pluginId: plugin.id,\n operation: \"validate-hydrated-config\",\n cause: validationError.zodError,\n }),\n ),\n );\n\n // Create a long-lived scope for this plugin instance. Initialize\n // returns a Layer which is built against this scope, so scoped\n // resources (DB pools, caches) release on plugin shutdown.\n const scope = yield* Scope.make();\n\n // Build the plugin's Layer within the scope.\n // On failure, close the scope immediately so scoped resources\n // (DB pools, caches) are released — otherwise every failed\n // initialization leaks until the process exits.\n const effectContext = yield* Effect.gen(function* () {\n const layer = yield* plugin\n .initialize({ variables: _variables, secrets: hydratedConfig.secrets }, plugins ?? {})\n .pipe(\n Effect.provideService(PluginIdTag, plugin.id),\n Effect.provideService(Scope.Scope, scope),\n );\n\n return yield* Layer.buildWithScope(layer, scope).pipe(\n Effect.provideService(PluginIdTag, plugin.id),\n Effect.provideService(Scope.Scope, scope),\n Effect.mapError((error) =>\n toPluginRuntimeError(error, plugin.id, undefined, \"initialize-layer\"),\n ),\n );\n }).pipe(\n Effect.onExit((exit) =>\n Exit.isSuccess(exit)\n ? Effect.void\n : Scope.close(scope, exit).pipe(\n Effect.catchCause((closeCause) =>\n Effect.logWarning(\n `Failed to close scope for plugin ${plugin.id} after initialize error`,\n closeCause,\n ),\n ),\n ),\n ),\n Effect.tapError((error) =>\n Effect.logError(\n `Plugin ${plugin.id} failed during initialize-plugin: ${String(error)}`,\n ),\n ),\n Effect.mapError((error) =>\n toPluginRuntimeError(error, plugin.id, undefined, \"initialize-plugin\"),\n ),\n );\n\n return {\n plugin,\n metadata: pluginInstance.metadata,\n config: { variables: _variables, secrets: hydratedConfig.secrets },\n effectContext,\n scope,\n } satisfies InitializedPlugin<T>;\n }),\n };\n }),\n);\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"plugin-loader.service.mjs","names":[],"sources":["../../../src/runtime/services/plugin-loader.service.ts"],"sourcesContent":["import type { InferSchemaInput, InferSchemaOutput } from \"@orpc/contract\";\nimport { Context, Effect, Exit, Layer, Scope } from \"effect\";\nimport type { z } from \"zod\";\nimport { PluginIdTag } from \"../../plugin\";\nimport type {\n AnyPlugin,\n AnyPluginConstructor,\n InitializedPlugin,\n LoadedPlugin,\n PluginInstance,\n PluginMetadata,\n PluginRegistry,\n} from \"../../types\";\nimport type { PluginWarningInfo } from \"../errors\";\nimport { PluginRuntimeError, toPluginRuntimeError } from \"../errors\";\nimport { validate } from \"../validation\";\nimport { ModuleFederationService } from \"./module-federation.service\";\nimport { SecretsService } from \"./secrets.service\";\n\n/**\n * Evaluate a plugin's `warnings` function against the validated config.\n * Fail-safe: a throwing warnings function becomes a warning itself rather\n * than failing initialization. Strings are normalized to `PluginWarningInfo`\n * with the plugin's registry key.\n */\nconst collectPluginWarnings = (\n plugin: AnyPlugin,\n config: { variables: unknown; secrets: unknown },\n): PluginWarningInfo[] => {\n const warningsFn = plugin.warnings;\n if (!warningsFn) return [];\n try {\n const raw = warningsFn(config as never);\n return raw.map((warning) =>\n typeof warning === \"string\" ? { pluginKey: plugin.id, message: warning } : warning,\n );\n } catch (error) {\n return [\n {\n pluginKey: plugin.id,\n message: `Plugin warnings check failed: ${error instanceof Error ? error.message : String(error)}`,\n },\n ];\n }\n};\n\nexport class PluginRegistryTag extends Context.Service<PluginRegistryTag, PluginRegistry>()(\n \"PluginRegistry\",\n) {}\n\nexport class PluginMapTag extends Context.Service<\n PluginMapTag,\n Record<string, AnyPluginConstructor>\n>()(\"PluginMap\") {}\n\nexport interface RegistryServiceShape {\n get: (\n pluginId: string,\n ) => Effect.Effect<\n { constructor: (new () => AnyPlugin) | null; metadata: PluginMetadata },\n PluginRuntimeError\n >;\n getModule: (pluginId: string) => Effect.Effect<AnyPluginConstructor | null>;\n}\n\nexport class RegistryService extends Context.Service<RegistryService, RegistryServiceShape>()(\n \"RegistryService\",\n) {}\n\nexport const RegistryServiceDefault = Layer.effect(\n RegistryService,\n Effect.gen(function* () {\n const registry = yield* PluginRegistryTag;\n const pluginMap = yield* PluginMapTag;\n\n return {\n get: (pluginId: string) =>\n Effect.gen(function* () {\n const entry = registry[pluginId];\n\n if (!entry) {\n return yield* new PluginRuntimeError({\n pluginId,\n operation: \"validate-plugin-id\",\n cause: new Error(`Plugin ${pluginId} not found in registry`),\n });\n }\n\n if (\"module\" in entry) {\n return {\n constructor: entry.module,\n metadata: {\n remoteUrl: entry.remote || \"\",\n version: entry.version,\n description: entry.description,\n } as PluginMetadata,\n };\n }\n\n return {\n constructor: null,\n metadata: {\n remoteUrl: entry.remote,\n version: entry.version,\n description: entry.description,\n } as PluginMetadata,\n };\n }),\n\n getModule: (pluginId: string) => Effect.succeed(pluginMap[pluginId] || null),\n };\n }),\n);\n\nexport interface PluginLoaderServiceShape {\n loadPlugin: (pluginId: string) => Effect.Effect<LoadedPlugin, PluginRuntimeError>;\n instantiatePlugin: <T extends AnyPlugin>(\n pluginId: string,\n loadedPlugin: LoadedPlugin<T>,\n ) => Effect.Effect<PluginInstance<T>, PluginRuntimeError>;\n initializePlugin: <T extends AnyPlugin>(\n pluginInstance: PluginInstance<T>,\n config: {\n variables: InferSchemaInput<T[\"configSchema\"][\"variables\"]>;\n secrets: InferSchemaInput<T[\"configSchema\"][\"secrets\"]>;\n },\n plugins?: Record<string, unknown>,\n ) => Effect.Effect<InitializedPlugin<T>, PluginRuntimeError>;\n}\n\nexport class PluginLoaderService extends Context.Service<\n PluginLoaderService,\n PluginLoaderServiceShape\n>()(\"PluginLoaderService\") {}\n\nexport const PluginLoaderServiceDefault = Layer.effect(\n PluginLoaderService,\n Effect.gen(function* () {\n const moduleFederationService = yield* ModuleFederationService;\n const secretsService = yield* SecretsService;\n const registryService = yield* RegistryService;\n\n const resolveUrl = (baseUrl: string, version?: string): string =>\n version && version !== \"latest\" ? baseUrl.replace(\"@latest\", `@${version}`) : baseUrl;\n\n return {\n loadPlugin: (pluginId: string) =>\n Effect.gen(function* () {\n const entry = yield* registryService.get(pluginId);\n\n if (entry.constructor) {\n yield* Effect.logDebug(\"Loading plugin from direct module\", { pluginId });\n\n return {\n ctor: entry.constructor,\n metadata: entry.metadata,\n } satisfies LoadedPlugin;\n }\n\n const url = entry.metadata.remoteUrl;\n if (!url) {\n return yield* new PluginRuntimeError({\n pluginId,\n operation: \"load-plugin\",\n cause: new Error(`Plugin ${pluginId} has no module or remote URL configured`),\n });\n }\n\n const resolvedUrl = resolveUrl(url);\n\n yield* moduleFederationService.registerRemote(pluginId, resolvedUrl).pipe(\n Effect.tapError((error) =>\n Effect.logError(`Plugin ${pluginId} failed during register-remote: ${String(error)}`),\n ),\n Effect.mapError((error) =>\n toPluginRuntimeError(error, pluginId, undefined, \"register-remote\"),\n ),\n );\n\n yield* Effect.logDebug(\"Loading plugin from remote\", { pluginId, url: resolvedUrl });\n\n const ctor = yield* moduleFederationService\n .loadRemoteConstructor(pluginId, resolvedUrl)\n .pipe(\n Effect.tapError((error) =>\n Effect.logError(`Plugin ${pluginId} failed during load-remote: ${String(error)}`),\n ),\n Effect.mapError((error) =>\n toPluginRuntimeError(error, pluginId, undefined, \"load-remote\"),\n ),\n );\n\n return {\n ctor,\n metadata: entry.metadata,\n } satisfies LoadedPlugin;\n }),\n\n instantiatePlugin: <T extends AnyPlugin>(pluginId: string, loadedPlugin: LoadedPlugin<T>) =>\n Effect.gen(function* () {\n const instance = yield* Effect.try(() => new loadedPlugin.ctor()).pipe(\n Effect.tapError((error) =>\n Effect.logError(`Plugin ${pluginId} failed during instantiate-plugin: ${error}`),\n ),\n Effect.mapError((error) =>\n toPluginRuntimeError(error, pluginId, undefined, \"instantiate-plugin\"),\n ),\n );\n\n (instance.id as string) = pluginId;\n\n return {\n plugin: instance,\n metadata: loadedPlugin.metadata,\n } satisfies PluginInstance<T>;\n }),\n\n initializePlugin: <T extends AnyPlugin>(\n pluginInstance: PluginInstance<T>,\n config: {\n variables: InferSchemaInput<T[\"configSchema\"][\"variables\"]>;\n secrets: InferSchemaInput<T[\"configSchema\"][\"secrets\"]>;\n },\n plugins?: Record<string, unknown>,\n ) =>\n Effect.gen(function* () {\n const { plugin } = pluginInstance;\n\n // Validate and hydrate config\n const validatedVariables = yield* validate(\n plugin.configSchema.variables as z.ZodSchema<\n InferSchemaOutput<T[\"configSchema\"][\"variables\"]>\n >,\n config.variables,\n plugin.id,\n \"config\",\n ).pipe(\n Effect.mapError(\n (validationError) =>\n new PluginRuntimeError({\n pluginId: plugin.id,\n operation: \"validate-config\",\n cause: validationError.zodError,\n }),\n ),\n );\n\n // Validate secrets\n const validatedSecrets = yield* validate(\n plugin.configSchema.secrets as z.ZodSchema<\n InferSchemaOutput<T[\"configSchema\"][\"secrets\"]>\n >,\n config.secrets,\n plugin.id,\n \"config\",\n ).pipe(\n Effect.mapError(\n (validationError) =>\n new PluginRuntimeError({\n pluginId: plugin.id,\n operation: \"validate-secrets\",\n cause: validationError.zodError,\n }),\n ),\n );\n\n // Hydrate secrets in variables\n const hydratedConfig = yield* secretsService.hydrateSecrets({\n variables: validatedVariables,\n secrets: validatedSecrets,\n });\n\n const _variables = yield* validate(\n plugin.configSchema.variables as z.ZodSchema<\n InferSchemaOutput<T[\"configSchema\"][\"variables\"]>\n >,\n hydratedConfig.variables,\n plugin.id,\n \"config\",\n ).pipe(\n Effect.mapError(\n (validationError) =>\n new PluginRuntimeError({\n pluginId: plugin.id,\n operation: \"validate-hydrated-config\",\n cause: validationError.zodError,\n }),\n ),\n );\n\n // Create a long-lived scope for this plugin instance. Initialize\n // returns a Layer which is built against this scope, so scoped\n // resources (DB pools, caches) release on plugin shutdown.\n const scope = yield* Scope.make();\n\n // Build the plugin's Layer within the scope.\n // On failure, close the scope immediately so scoped resources\n // (DB pools, caches) are released — otherwise every failed\n // initialization leaks until the process exits.\n const effectContext = yield* Effect.gen(function* () {\n const layer = yield* plugin\n .initialize({ variables: _variables, secrets: hydratedConfig.secrets }, plugins ?? {})\n .pipe(\n Effect.provideService(PluginIdTag, plugin.id),\n Effect.provideService(Scope.Scope, scope),\n );\n\n return yield* Layer.buildWithScope(layer, scope).pipe(\n Effect.provideService(PluginIdTag, plugin.id),\n Effect.provideService(Scope.Scope, scope),\n Effect.mapError((error) =>\n toPluginRuntimeError(error, plugin.id, undefined, \"initialize-layer\"),\n ),\n );\n }).pipe(\n Effect.onExit((exit) =>\n Exit.isSuccess(exit)\n ? Effect.void\n : Scope.close(scope, exit).pipe(\n Effect.catchCause((closeCause) =>\n Effect.logWarning(\n `Failed to close scope for plugin ${plugin.id} after initialize error`,\n closeCause,\n ),\n ),\n ),\n ),\n Effect.tapError((error) =>\n Effect.logError(\n `Plugin ${plugin.id} failed during initialize-plugin: ${String(error)}`,\n ),\n ),\n Effect.mapError((error) =>\n toPluginRuntimeError(error, plugin.id, undefined, \"initialize-plugin\"),\n ),\n );\n\n return {\n plugin,\n metadata: pluginInstance.metadata,\n config: { variables: _variables, secrets: hydratedConfig.secrets },\n effectContext,\n scope,\n warnings: collectPluginWarnings(plugin, {\n variables: _variables,\n secrets: hydratedConfig.secrets,\n }),\n } satisfies InitializedPlugin<T>;\n }),\n };\n }),\n);\n"],"mappings":"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"}
|
|
@@ -6,7 +6,7 @@ function manifestUrl(remoteUrl) {
|
|
|
6
6
|
return remoteUrl.endsWith("/") ? `${remoteUrl}mf-manifest.json` : `${remoteUrl}/mf-manifest.json`;
|
|
7
7
|
}
|
|
8
8
|
function normalizeBaseUrl(remoteUrl) {
|
|
9
|
-
return (remoteUrl.split("#")[0] ?? remoteUrl).replace(/\/(mf-manifest\.json|remoteEntry
|
|
9
|
+
return (remoteUrl.split("#")[0] ?? remoteUrl).replace(/\/(mf-manifest\.json|remoteEntry(?:\.[^/]+)?\.js)$/i, "");
|
|
10
10
|
}
|
|
11
11
|
function compareSharedIdentity(remoteShared, expectedVersions) {
|
|
12
12
|
const mismatches = [];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shared-identity.cjs","names":["isEffectCriticalSharedDep"],"sources":["../../../src/runtime/services/shared-identity.ts"],"sourcesContent":["import { isEffectCriticalSharedDep } from \"../../shared-deps-spec\";\n\ninterface IdentityManifest {\n metaData?: { pluginVersion?: string; name?: string };\n shared?: Array<{ name: string; version?: string }>;\n}\n\nexport interface SharedIdentityMismatch {\n name: string;\n expected: string;\n actual: string | null;\n}\n\nconst MANIFEST_TIMEOUT_MS = 15_000;\n\nfunction manifestUrl(remoteUrl: string): string {\n return remoteUrl.endsWith(\"/\") ? `${remoteUrl}mf-manifest.json` : `${remoteUrl}/mf-manifest.json`;\n}\n\nfunction normalizeBaseUrl(remoteUrl: string): string {\n const withoutHash = remoteUrl.split(\"#\")[0] ?? remoteUrl;\n return withoutHash.replace(/\\/(mf-manifest\\.json|remoteEntry
|
|
1
|
+
{"version":3,"file":"shared-identity.cjs","names":["isEffectCriticalSharedDep"],"sources":["../../../src/runtime/services/shared-identity.ts"],"sourcesContent":["import { isEffectCriticalSharedDep } from \"../../shared-deps-spec\";\n\ninterface IdentityManifest {\n metaData?: { pluginVersion?: string; name?: string };\n shared?: Array<{ name: string; version?: string }>;\n}\n\nexport interface SharedIdentityMismatch {\n name: string;\n expected: string;\n actual: string | null;\n}\n\nconst MANIFEST_TIMEOUT_MS = 15_000;\n\nfunction manifestUrl(remoteUrl: string): string {\n return remoteUrl.endsWith(\"/\") ? `${remoteUrl}mf-manifest.json` : `${remoteUrl}/mf-manifest.json`;\n}\n\nfunction normalizeBaseUrl(remoteUrl: string): string {\n const withoutHash = remoteUrl.split(\"#\")[0] ?? remoteUrl;\n return withoutHash.replace(/\\/(mf-manifest\\.json|remoteEntry(?:\\.[^/]+)?\\.js)$/i, \"\");\n}\n\nexport function compareSharedIdentity(\n remoteShared: Array<{ name: string; version?: string }> | undefined,\n expectedVersions: Map<string, string>,\n): SharedIdentityMismatch[] {\n const mismatches: SharedIdentityMismatch[] = [];\n const remoteByName = new Map((remoteShared ?? []).map((s) => [s.name, s]));\n\n for (const [name, expected] of expectedVersions.entries()) {\n if (!isEffectCriticalSharedDep(name)) continue;\n const remoteEntry = remoteByName.get(name);\n if (!remoteEntry) continue;\n if (remoteEntry.version && remoteEntry.version !== expected) {\n mismatches.push({ name, expected, actual: remoteEntry.version });\n }\n }\n\n return mismatches;\n}\n\nexport function describeSharedIdentityMismatch(\n pluginId: string,\n mismatches: SharedIdentityMismatch[],\n hostExpectation: string,\n): string {\n const lines = mismatches.map(\n (m) =>\n ` ${m.name}: expected ${m.expected} (from ${hostExpectation}), got ${m.actual ?? \"missing\"}`,\n );\n return (\n `[SharedIdentity] Refusing to load plugin \"${pluginId}\": shared dependency version skew.\\n` +\n `${lines.join(\"\\n\")}\\n` +\n `Run \"bos mf check\" for the full report. Fix: rebuild and redeploy the host and this plugin together (single release train, e.g. \"bos publish --deploy --packages local\").`\n );\n}\n\nexport async function fetchRemoteIdentityManifest(\n remoteUrl: string,\n): Promise<IdentityManifest | null> {\n const base = normalizeBaseUrl(remoteUrl);\n const url = manifestUrl(base);\n const res = await fetch(url, { signal: AbortSignal.timeout(MANIFEST_TIMEOUT_MS) });\n if (!res.ok) return null;\n return (await res.json()) as IdentityManifest;\n}\n"],"mappings":";;;AAaA,MAAM,sBAAsB;AAE5B,SAAS,YAAY,WAA2B;CAC9C,OAAO,UAAU,SAAS,GAAG,IAAI,GAAG,UAAU,oBAAoB,GAAG,UAAU;AACjF;AAEA,SAAS,iBAAiB,WAA2B;CAEnD,QADoB,UAAU,MAAM,GAAG,CAAC,CAAC,MAAM,UAC7B,CAAC,QAAQ,uDAAuD,EAAE;AACtF;AAEA,SAAgB,sBACd,cACA,kBAC0B;CAC1B,MAAM,aAAuC,CAAC;CAC9C,MAAM,eAAe,IAAI,KAAK,gBAAgB,CAAC,EAAC,CAAE,KAAK,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;CAEzE,KAAK,MAAM,CAAC,MAAM,aAAa,iBAAiB,QAAQ,GAAG;EACzD,IAAI,CAACA,mDAA0B,IAAI,GAAG;EACtC,MAAM,cAAc,aAAa,IAAI,IAAI;EACzC,IAAI,CAAC,aAAa;EAClB,IAAI,YAAY,WAAW,YAAY,YAAY,UACjD,WAAW,KAAK;GAAE;GAAM;GAAU,QAAQ,YAAY;EAAQ,CAAC;CAEnE;CAEA,OAAO;AACT;AAEA,SAAgB,+BACd,UACA,YACA,iBACQ;CAKR,OACE,6CAA6C,SAAS,sCAL1C,WAAW,KACtB,MACC,KAAK,EAAE,KAAK,aAAa,EAAE,SAAS,SAAS,gBAAgB,SAAS,EAAE,UAAU,WAI7E,CAAC,CAAC,KAAK,IAAI,EAAE;AAGxB;AAEA,eAAsB,4BACpB,WACkC;CAElC,MAAM,MAAM,YADC,iBAAiB,SACH,CAAC;CAC5B,MAAM,MAAM,MAAM,MAAM,KAAK,EAAE,QAAQ,YAAY,QAAQ,mBAAmB,EAAE,CAAC;CACjF,IAAI,CAAC,IAAI,IAAI,OAAO;CACpB,OAAQ,MAAM,IAAI,KAAK;AACzB"}
|
|
@@ -6,7 +6,7 @@ function manifestUrl(remoteUrl) {
|
|
|
6
6
|
return remoteUrl.endsWith("/") ? `${remoteUrl}mf-manifest.json` : `${remoteUrl}/mf-manifest.json`;
|
|
7
7
|
}
|
|
8
8
|
function normalizeBaseUrl(remoteUrl) {
|
|
9
|
-
return (remoteUrl.split("#")[0] ?? remoteUrl).replace(/\/(mf-manifest\.json|remoteEntry
|
|
9
|
+
return (remoteUrl.split("#")[0] ?? remoteUrl).replace(/\/(mf-manifest\.json|remoteEntry(?:\.[^/]+)?\.js)$/i, "");
|
|
10
10
|
}
|
|
11
11
|
function compareSharedIdentity(remoteShared, expectedVersions) {
|
|
12
12
|
const mismatches = [];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shared-identity.mjs","names":[],"sources":["../../../src/runtime/services/shared-identity.ts"],"sourcesContent":["import { isEffectCriticalSharedDep } from \"../../shared-deps-spec\";\n\ninterface IdentityManifest {\n metaData?: { pluginVersion?: string; name?: string };\n shared?: Array<{ name: string; version?: string }>;\n}\n\nexport interface SharedIdentityMismatch {\n name: string;\n expected: string;\n actual: string | null;\n}\n\nconst MANIFEST_TIMEOUT_MS = 15_000;\n\nfunction manifestUrl(remoteUrl: string): string {\n return remoteUrl.endsWith(\"/\") ? `${remoteUrl}mf-manifest.json` : `${remoteUrl}/mf-manifest.json`;\n}\n\nfunction normalizeBaseUrl(remoteUrl: string): string {\n const withoutHash = remoteUrl.split(\"#\")[0] ?? remoteUrl;\n return withoutHash.replace(/\\/(mf-manifest\\.json|remoteEntry
|
|
1
|
+
{"version":3,"file":"shared-identity.mjs","names":[],"sources":["../../../src/runtime/services/shared-identity.ts"],"sourcesContent":["import { isEffectCriticalSharedDep } from \"../../shared-deps-spec\";\n\ninterface IdentityManifest {\n metaData?: { pluginVersion?: string; name?: string };\n shared?: Array<{ name: string; version?: string }>;\n}\n\nexport interface SharedIdentityMismatch {\n name: string;\n expected: string;\n actual: string | null;\n}\n\nconst MANIFEST_TIMEOUT_MS = 15_000;\n\nfunction manifestUrl(remoteUrl: string): string {\n return remoteUrl.endsWith(\"/\") ? `${remoteUrl}mf-manifest.json` : `${remoteUrl}/mf-manifest.json`;\n}\n\nfunction normalizeBaseUrl(remoteUrl: string): string {\n const withoutHash = remoteUrl.split(\"#\")[0] ?? remoteUrl;\n return withoutHash.replace(/\\/(mf-manifest\\.json|remoteEntry(?:\\.[^/]+)?\\.js)$/i, \"\");\n}\n\nexport function compareSharedIdentity(\n remoteShared: Array<{ name: string; version?: string }> | undefined,\n expectedVersions: Map<string, string>,\n): SharedIdentityMismatch[] {\n const mismatches: SharedIdentityMismatch[] = [];\n const remoteByName = new Map((remoteShared ?? []).map((s) => [s.name, s]));\n\n for (const [name, expected] of expectedVersions.entries()) {\n if (!isEffectCriticalSharedDep(name)) continue;\n const remoteEntry = remoteByName.get(name);\n if (!remoteEntry) continue;\n if (remoteEntry.version && remoteEntry.version !== expected) {\n mismatches.push({ name, expected, actual: remoteEntry.version });\n }\n }\n\n return mismatches;\n}\n\nexport function describeSharedIdentityMismatch(\n pluginId: string,\n mismatches: SharedIdentityMismatch[],\n hostExpectation: string,\n): string {\n const lines = mismatches.map(\n (m) =>\n ` ${m.name}: expected ${m.expected} (from ${hostExpectation}), got ${m.actual ?? \"missing\"}`,\n );\n return (\n `[SharedIdentity] Refusing to load plugin \"${pluginId}\": shared dependency version skew.\\n` +\n `${lines.join(\"\\n\")}\\n` +\n `Run \"bos mf check\" for the full report. Fix: rebuild and redeploy the host and this plugin together (single release train, e.g. \"bos publish --deploy --packages local\").`\n );\n}\n\nexport async function fetchRemoteIdentityManifest(\n remoteUrl: string,\n): Promise<IdentityManifest | null> {\n const base = normalizeBaseUrl(remoteUrl);\n const url = manifestUrl(base);\n const res = await fetch(url, { signal: AbortSignal.timeout(MANIFEST_TIMEOUT_MS) });\n if (!res.ok) return null;\n return (await res.json()) as IdentityManifest;\n}\n"],"mappings":";;;AAaA,MAAM,sBAAsB;AAE5B,SAAS,YAAY,WAA2B;CAC9C,OAAO,UAAU,SAAS,GAAG,IAAI,GAAG,UAAU,oBAAoB,GAAG,UAAU;AACjF;AAEA,SAAS,iBAAiB,WAA2B;CAEnD,QADoB,UAAU,MAAM,GAAG,CAAC,CAAC,MAAM,UAC7B,CAAC,QAAQ,uDAAuD,EAAE;AACtF;AAEA,SAAgB,sBACd,cACA,kBAC0B;CAC1B,MAAM,aAAuC,CAAC;CAC9C,MAAM,eAAe,IAAI,KAAK,gBAAgB,CAAC,EAAC,CAAE,KAAK,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;CAEzE,KAAK,MAAM,CAAC,MAAM,aAAa,iBAAiB,QAAQ,GAAG;EACzD,IAAI,CAAC,0BAA0B,IAAI,GAAG;EACtC,MAAM,cAAc,aAAa,IAAI,IAAI;EACzC,IAAI,CAAC,aAAa;EAClB,IAAI,YAAY,WAAW,YAAY,YAAY,UACjD,WAAW,KAAK;GAAE;GAAM;GAAU,QAAQ,YAAY;EAAQ,CAAC;CAEnE;CAEA,OAAO;AACT;AAEA,SAAgB,+BACd,UACA,YACA,iBACQ;CAKR,OACE,6CAA6C,SAAS,sCAL1C,WAAW,KACtB,MACC,KAAK,EAAE,KAAK,aAAa,EAAE,SAAS,SAAS,gBAAgB,SAAS,EAAE,UAAU,WAI7E,CAAC,CAAC,KAAK,IAAI,EAAE;AAGxB;AAEA,eAAsB,4BACpB,WACkC;CAElC,MAAM,MAAM,YADC,iBAAiB,SACH,CAAC;CAC5B,MAAM,MAAM,MAAM,MAAM,KAAK,EAAE,QAAQ,YAAY,QAAQ,mBAAmB,EAAE,CAAC;CACjF,IAAI,CAAC,IAAI,IAAI,OAAO;CACpB,OAAQ,MAAM,IAAI,KAAK;AACzB"}
|
package/dist/types.d.cts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import { PluginWarningInfo } from "./runtime/errors.cjs";
|
|
1
2
|
import { Plugin } from "./plugin.cjs";
|
|
3
|
+
import { AnyContractRouter, AnySchema, InferSchemaInput, InferSchemaOutput } from "@orpc/contract";
|
|
2
4
|
import { ContractedRouter, RouterClient } from "@orpc/server";
|
|
3
5
|
import { Context, Scope } from "effect";
|
|
4
|
-
import { AnyContractRouter, AnySchema, InferSchemaInput, InferSchemaOutput } from "@orpc/contract";
|
|
5
6
|
//#region src/types.d.ts
|
|
6
7
|
/**
|
|
7
8
|
* Registry bindings interface - populated via module augmentation
|
|
@@ -16,6 +17,18 @@ import { AnyContractRouter, AnySchema, InferSchemaInput, InferSchemaOutput } fro
|
|
|
16
17
|
* ```
|
|
17
18
|
*/
|
|
18
19
|
interface RegisteredPlugins {}
|
|
20
|
+
type ModuleTransport = "inproc" | "rpc" | "mf";
|
|
21
|
+
type ModuleSurface = "api" | "ui" | "jobs";
|
|
22
|
+
interface ModuleEndpoint {
|
|
23
|
+
readonly transport: ModuleTransport;
|
|
24
|
+
readonly surface?: ModuleSurface;
|
|
25
|
+
readonly url: string;
|
|
26
|
+
readonly path?: `/${string}`;
|
|
27
|
+
readonly manifest?: string;
|
|
28
|
+
}
|
|
29
|
+
type PluginTransport = ModuleTransport;
|
|
30
|
+
type PluginSurface = ModuleSurface;
|
|
31
|
+
type PluginEndpoint = ModuleEndpoint;
|
|
19
32
|
/**
|
|
20
33
|
* Base type for any plugin instance.
|
|
21
34
|
*/
|
|
@@ -38,10 +51,12 @@ type AnyPluginConstructor = {
|
|
|
38
51
|
type PluginRegistryEntry = {
|
|
39
52
|
module: AnyPluginConstructor;
|
|
40
53
|
remote?: string;
|
|
54
|
+
endpoint?: PluginEndpoint;
|
|
41
55
|
version?: string;
|
|
42
56
|
description?: string;
|
|
43
57
|
} | {
|
|
44
58
|
remote: string;
|
|
59
|
+
endpoint?: PluginEndpoint;
|
|
45
60
|
version?: string;
|
|
46
61
|
description?: string;
|
|
47
62
|
};
|
|
@@ -106,7 +121,14 @@ type PluginClientType<T> = RouterClient<PluginRouterType<T>>;
|
|
|
106
121
|
type PluginServicesEntry<T = any> = {
|
|
107
122
|
client: (context?: PluginContextInput<T>) => PluginClientType<T>;
|
|
108
123
|
router: PluginRouterType<T>;
|
|
124
|
+
endpoint?: PluginEndpoint;
|
|
125
|
+
};
|
|
126
|
+
type ModuleClientEntry<C extends AnyContractRouter = AnyContractRouter> = {
|
|
127
|
+
client: (context?: Record<string, unknown>) => RouterClient<ContractedRouter<C, any>>;
|
|
128
|
+
router?: ContractedRouter<C, any>;
|
|
129
|
+
endpoint?: PluginEndpoint;
|
|
109
130
|
};
|
|
131
|
+
type PluginClientEntry<C extends AnyContractRouter = AnyContractRouter> = ModuleClientEntry<C>;
|
|
110
132
|
/**
|
|
111
133
|
* Extract plugin type from registered plugins by key
|
|
112
134
|
* @param K - The plugin key
|
|
@@ -181,6 +203,8 @@ interface InitializedPlugin<T extends AnyPlugin = AnyPlugin> {
|
|
|
181
203
|
*/
|
|
182
204
|
readonly effectContext: Context.Context<any>;
|
|
183
205
|
readonly scope: Scope.Closeable;
|
|
206
|
+
/** Non-fatal config warnings collected during initialization (empty when none). */
|
|
207
|
+
readonly warnings: PluginWarningInfo[];
|
|
184
208
|
}
|
|
185
209
|
/**
|
|
186
210
|
* Helper type to detect type errors when looking up RegisteredPlugins
|
|
@@ -244,5 +268,5 @@ interface PluginRuntimeConfig<R extends Record<string, PluginRegistryEntry> = Re
|
|
|
244
268
|
secrets?: SecretsConfig;
|
|
245
269
|
}
|
|
246
270
|
//#endregion
|
|
247
|
-
export { AnyPlugin, AnyPluginConstructor, EveryPlugin, ExtractPluginType, InferRegistryFromEntries, InitializedPlugin, LoadedPlugin, PluginClientType, PluginConfigInput, PluginContext, PluginContextInput, PluginContract, PluginInstance, PluginMetadata, PluginRegistry, PluginRegistryEntry, PluginRouterType, PluginRuntimeConfig, PluginSecrets, PluginServicesEntry, PluginVariables, RegisteredPlugin, RegisteredPlugins, SecretsConfig, UsePluginResult };
|
|
271
|
+
export { AnyPlugin, AnyPluginConstructor, EveryPlugin, ExtractPluginType, InferRegistryFromEntries, InitializedPlugin, LoadedPlugin, ModuleClientEntry, ModuleEndpoint, ModuleSurface, ModuleTransport, PluginClientEntry, PluginClientType, PluginConfigInput, PluginContext, PluginContextInput, PluginContract, PluginEndpoint, PluginInstance, PluginMetadata, PluginRegistry, PluginRegistryEntry, PluginRouterType, PluginRuntimeConfig, PluginSecrets, PluginServicesEntry, PluginSurface, PluginTransport, PluginVariables, RegisteredPlugin, RegisteredPlugins, SecretsConfig, UsePluginResult };
|
|
248
272
|
//# sourceMappingURL=types.d.cts.map
|
package/dist/types.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.cts","names":[],"sources":["../src/types.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.d.cts","names":[],"sources":["../src/types.ts"],"mappings":";;;;;;;;;;;;;;;;;;UAwBiB;KAEL;KAEA;UAEK;WACN,WAAW;WACX,UAAU;WACV;WACA;WACA;;KAGC,kBAAkB;KAElB,gBAAgB;KAEhB,iBAAiB;;;;KAKjB,YAAY,OAAO,mBAAmB,WAAW,WAAW;;;;KAK5D;UACF;EACR;IACE,UAAU;IACV,WAAW;IACX,SAAS;IACT,SAAS;;;;;;KAOD;EAEN,QAAQ;EACR;EACA,WAAW;EACX;EACA;;EAEA;EAAgB,WAAW;EAAgB;EAAkB;;;;;KAKvD,kBAAkB,KAAK;EAAY,cAAc;IAAM;;;;KAKvD,yBAAyB,UAAU,eAAe,2BAC3D,WAAW,IAAI,EAAE;EAAa,cAAc;IACzC,IACA,gBAAgB,oBACd,kBAAkB;;;;KAOd,eAAe,KAAK;EAC9B;IAAW,gBAAgB,UAAU;;IAEnC;;;;KAMQ,gBAAgB,KAAK;EAAY;IAAW,iBAAiB,UAAU;;IAC/E;;;;KAMQ,cAAc,KAAK;EAAY;IAAW,eAAe,UAAU;;IAC3E;;;;KAMQ,cAAc,KAAK;EAC7B;IAAW,eAAe,UAAU;;IAElC;;;;;KAOQ,iBAAiB,KAAK,iBAAiB,eAAe;;;;KAKtD,iBAAiB,KAAK,aAAa,iBAAiB;;;;;;KAOpD,oBAAoB;EAC9B,SAAS,UAAU,mBAAmB,OAAO,iBAAiB;EAC9D,QAAQ,iBAAiB;EACzB,WAAW;;KAGD,kBAAkB,UAAU,oBAAoB;EAC1D,SAAS,UAAU,4BAA4B,aAAa,iBAAiB;EAC7E,SAAS,iBAAiB;EAC1B,WAAW;;KAGD,kBAAkB,UAAU,oBAAoB,qBAC1D,kBAAkB;;;;;;KAOR,iBAAiB,gBAAgB,GAAG,IAAI,qBAAqB,EAAE;EACzE,eAAe;IAEb;EACE,gBAAgB,UAAU;EAC1B,iBAAiB,UAAU;EAC3B,eAAe,UAAU;EACzB,eAAe,wBAAwB;IAEvC,OAAO,GAAG,GAAG,GAAG;;;;KAOV,mBAAmB,KAC7B,cAAc,WAAW,YAAY,iBAAiB,cAAc;;;;KAK1D,kBAAkB;EAC5B,WAAW,iBAAiB,gBAAgB;EAC5C,SAAS,iBAAiB,cAAc;;;;;KAM9B;WACD;WACA;WACA;;;;;KAMC,iBAAiB,eAAe;;;;;UAM3B;GACd;;;;;UAMc,aAAa,UAAU,YAAY;WACzC,gBAAgB;WAChB,UAAU;;;;;UAMJ,eAAe,UAAU,YAAY;WAC3C,QAAQ;WACR,UAAU;;;;;UAMJ,kBAAkB,UAAU,YAAY;WAC9C,QAAQ;WACR,UAAU;WACV;IACP,WAAW,kBAAkB;IAC7B,SAAS,kBAAkB;;;;;;;WAOpB,eAAe,QAAQ;WACvB,OAAO,MAAM;;WAEb,UAAU;;;;;KAMhB,oBAAoB,gBAAgB,GAAG,IAAI,qBAAqB,EAAE;EACrE,eAAe;IAEb;EACE,UAAU;EACV,WAAW;EACX,SAAS;EACT,SAAS;wBAGI,4IACF;;;;;;KAOL,gBAAgB,gBAAgB,GAAG,IAAI,qBACjD,oBAAoB,GAAG;WAER,eAAe,UAAU,mBAAmB,EAAE,QAAQ,iBAAiB,EAAE;WACzE,QAAQ,iBAAiB,EAAE;WAC3B,UAAU;WACV,aAAa,kBAAkB,iBAAiB,GAAG;IAE9D,oBAAoB,GAAG;;;;;;;KAQxB,WAAW,KAAK;EAAY,uBAAuB;IAAM,IAAI;;;;kBAKjD;;;;;;;;;;;;;;;;;;OAkBH,MACV,kBACA,SAAS,qBACP,gBAAgB,WAAW,UAAU,gBAAgB,GAAG,WAAW;;;;;UAMxD,oBACf,UAAU,eAAe,uBAAuB,eAAe;EAE/D,UAAU;EACV,UAAU"}
|
package/dist/types.d.mts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { PluginWarningInfo } from "./runtime/errors.mjs";
|
|
1
2
|
import { Plugin } from "./plugin.mjs";
|
|
2
3
|
import { Context, Scope } from "effect";
|
|
3
4
|
import { ContractedRouter, RouterClient } from "@orpc/server";
|
|
@@ -16,6 +17,18 @@ import { AnyContractRouter, AnySchema, InferSchemaInput, InferSchemaOutput } fro
|
|
|
16
17
|
* ```
|
|
17
18
|
*/
|
|
18
19
|
interface RegisteredPlugins {}
|
|
20
|
+
type ModuleTransport = "inproc" | "rpc" | "mf";
|
|
21
|
+
type ModuleSurface = "api" | "ui" | "jobs";
|
|
22
|
+
interface ModuleEndpoint {
|
|
23
|
+
readonly transport: ModuleTransport;
|
|
24
|
+
readonly surface?: ModuleSurface;
|
|
25
|
+
readonly url: string;
|
|
26
|
+
readonly path?: `/${string}`;
|
|
27
|
+
readonly manifest?: string;
|
|
28
|
+
}
|
|
29
|
+
type PluginTransport = ModuleTransport;
|
|
30
|
+
type PluginSurface = ModuleSurface;
|
|
31
|
+
type PluginEndpoint = ModuleEndpoint;
|
|
19
32
|
/**
|
|
20
33
|
* Base type for any plugin instance.
|
|
21
34
|
*/
|
|
@@ -38,10 +51,12 @@ type AnyPluginConstructor = {
|
|
|
38
51
|
type PluginRegistryEntry = {
|
|
39
52
|
module: AnyPluginConstructor;
|
|
40
53
|
remote?: string;
|
|
54
|
+
endpoint?: PluginEndpoint;
|
|
41
55
|
version?: string;
|
|
42
56
|
description?: string;
|
|
43
57
|
} | {
|
|
44
58
|
remote: string;
|
|
59
|
+
endpoint?: PluginEndpoint;
|
|
45
60
|
version?: string;
|
|
46
61
|
description?: string;
|
|
47
62
|
};
|
|
@@ -106,7 +121,14 @@ type PluginClientType<T> = RouterClient<PluginRouterType<T>>;
|
|
|
106
121
|
type PluginServicesEntry<T = any> = {
|
|
107
122
|
client: (context?: PluginContextInput<T>) => PluginClientType<T>;
|
|
108
123
|
router: PluginRouterType<T>;
|
|
124
|
+
endpoint?: PluginEndpoint;
|
|
125
|
+
};
|
|
126
|
+
type ModuleClientEntry<C extends AnyContractRouter = AnyContractRouter> = {
|
|
127
|
+
client: (context?: Record<string, unknown>) => RouterClient<ContractedRouter<C, any>>;
|
|
128
|
+
router?: ContractedRouter<C, any>;
|
|
129
|
+
endpoint?: PluginEndpoint;
|
|
109
130
|
};
|
|
131
|
+
type PluginClientEntry<C extends AnyContractRouter = AnyContractRouter> = ModuleClientEntry<C>;
|
|
110
132
|
/**
|
|
111
133
|
* Extract plugin type from registered plugins by key
|
|
112
134
|
* @param K - The plugin key
|
|
@@ -181,6 +203,8 @@ interface InitializedPlugin<T extends AnyPlugin = AnyPlugin> {
|
|
|
181
203
|
*/
|
|
182
204
|
readonly effectContext: Context.Context<any>;
|
|
183
205
|
readonly scope: Scope.Closeable;
|
|
206
|
+
/** Non-fatal config warnings collected during initialization (empty when none). */
|
|
207
|
+
readonly warnings: PluginWarningInfo[];
|
|
184
208
|
}
|
|
185
209
|
/**
|
|
186
210
|
* Helper type to detect type errors when looking up RegisteredPlugins
|
|
@@ -244,5 +268,5 @@ interface PluginRuntimeConfig<R extends Record<string, PluginRegistryEntry> = Re
|
|
|
244
268
|
secrets?: SecretsConfig;
|
|
245
269
|
}
|
|
246
270
|
//#endregion
|
|
247
|
-
export { AnyPlugin, AnyPluginConstructor, EveryPlugin, ExtractPluginType, InferRegistryFromEntries, InitializedPlugin, LoadedPlugin, PluginClientType, PluginConfigInput, PluginContext, PluginContextInput, PluginContract, PluginInstance, PluginMetadata, PluginRegistry, PluginRegistryEntry, PluginRouterType, PluginRuntimeConfig, PluginSecrets, PluginServicesEntry, PluginVariables, RegisteredPlugin, RegisteredPlugins, SecretsConfig, UsePluginResult };
|
|
271
|
+
export { AnyPlugin, AnyPluginConstructor, EveryPlugin, ExtractPluginType, InferRegistryFromEntries, InitializedPlugin, LoadedPlugin, ModuleClientEntry, ModuleEndpoint, ModuleSurface, ModuleTransport, PluginClientEntry, PluginClientType, PluginConfigInput, PluginContext, PluginContextInput, PluginContract, PluginEndpoint, PluginInstance, PluginMetadata, PluginRegistry, PluginRegistryEntry, PluginRouterType, PluginRuntimeConfig, PluginSecrets, PluginServicesEntry, PluginSurface, PluginTransport, PluginVariables, RegisteredPlugin, RegisteredPlugins, SecretsConfig, UsePluginResult };
|
|
248
272
|
//# sourceMappingURL=types.d.mts.map
|
package/dist/types.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.mts","names":[],"sources":["../src/types.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.d.mts","names":[],"sources":["../src/types.ts"],"mappings":";;;;;;;;;;;;;;;;;;UAwBiB;KAEL;KAEA;UAEK;WACN,WAAW;WACX,UAAU;WACV;WACA;WACA;;KAGC,kBAAkB;KAElB,gBAAgB;KAEhB,iBAAiB;;;;KAKjB,YAAY,OAAO,mBAAmB,WAAW,WAAW;;;;KAK5D;UACF;EACR;IACE,UAAU;IACV,WAAW;IACX,SAAS;IACT,SAAS;;;;;;KAOD;EAEN,QAAQ;EACR;EACA,WAAW;EACX;EACA;;EAEA;EAAgB,WAAW;EAAgB;EAAkB;;;;;KAKvD,kBAAkB,KAAK;EAAY,cAAc;IAAM;;;;KAKvD,yBAAyB,UAAU,eAAe,2BAC3D,WAAW,IAAI,EAAE;EAAa,cAAc;IACzC,IACA,gBAAgB,oBACd,kBAAkB;;;;KAOd,eAAe,KAAK;EAC9B;IAAW,gBAAgB,UAAU;;IAEnC;;;;KAMQ,gBAAgB,KAAK;EAAY;IAAW,iBAAiB,UAAU;;IAC/E;;;;KAMQ,cAAc,KAAK;EAAY;IAAW,eAAe,UAAU;;IAC3E;;;;KAMQ,cAAc,KAAK;EAC7B;IAAW,eAAe,UAAU;;IAElC;;;;;KAOQ,iBAAiB,KAAK,iBAAiB,eAAe;;;;KAKtD,iBAAiB,KAAK,aAAa,iBAAiB;;;;;;KAOpD,oBAAoB;EAC9B,SAAS,UAAU,mBAAmB,OAAO,iBAAiB;EAC9D,QAAQ,iBAAiB;EACzB,WAAW;;KAGD,kBAAkB,UAAU,oBAAoB;EAC1D,SAAS,UAAU,4BAA4B,aAAa,iBAAiB;EAC7E,SAAS,iBAAiB;EAC1B,WAAW;;KAGD,kBAAkB,UAAU,oBAAoB,qBAC1D,kBAAkB;;;;;;KAOR,iBAAiB,gBAAgB,GAAG,IAAI,qBAAqB,EAAE;EACzE,eAAe;IAEb;EACE,gBAAgB,UAAU;EAC1B,iBAAiB,UAAU;EAC3B,eAAe,UAAU;EACzB,eAAe,wBAAwB;IAEvC,OAAO,GAAG,GAAG,GAAG;;;;KAOV,mBAAmB,KAC7B,cAAc,WAAW,YAAY,iBAAiB,cAAc;;;;KAK1D,kBAAkB;EAC5B,WAAW,iBAAiB,gBAAgB;EAC5C,SAAS,iBAAiB,cAAc;;;;;KAM9B;WACD;WACA;WACA;;;;;KAMC,iBAAiB,eAAe;;;;;UAM3B;GACd;;;;;UAMc,aAAa,UAAU,YAAY;WACzC,gBAAgB;WAChB,UAAU;;;;;UAMJ,eAAe,UAAU,YAAY;WAC3C,QAAQ;WACR,UAAU;;;;;UAMJ,kBAAkB,UAAU,YAAY;WAC9C,QAAQ;WACR,UAAU;WACV;IACP,WAAW,kBAAkB;IAC7B,SAAS,kBAAkB;;;;;;;WAOpB,eAAe,QAAQ;WACvB,OAAO,MAAM;;WAEb,UAAU;;;;;KAMhB,oBAAoB,gBAAgB,GAAG,IAAI,qBAAqB,EAAE;EACrE,eAAe;IAEb;EACE,UAAU;EACV,WAAW;EACX,SAAS;EACT,SAAS;wBAGI,4IACF;;;;;;KAOL,gBAAgB,gBAAgB,GAAG,IAAI,qBACjD,oBAAoB,GAAG;WAER,eAAe,UAAU,mBAAmB,EAAE,QAAQ,iBAAiB,EAAE;WACzE,QAAQ,iBAAiB,EAAE;WAC3B,UAAU;WACV,aAAa,kBAAkB,iBAAiB,GAAG;IAE9D,oBAAoB,GAAG;;;;;;;KAQxB,WAAW,KAAK;EAAY,uBAAuB;IAAM,IAAI;;;;kBAKjD;;;;;;;;;;;;;;;;;;OAkBH,MACV,kBACA,SAAS,qBACP,gBAAgB,WAAW,UAAU,gBAAgB,GAAG,WAAW;;;;;UAMxD,oBACf,UAAU,eAAe,uBAAuB,eAAe;EAE/D,UAAU;EACV,UAAU"}
|
|
@@ -46,7 +46,7 @@ const WorkspaceVersionManifestSchema = zod.z.object({
|
|
|
46
46
|
* coordinate → a new version (and a new file).
|
|
47
47
|
*/
|
|
48
48
|
function composeVersionManifest(input) {
|
|
49
|
-
const { builtAt, ...hashedInputs } = input;
|
|
49
|
+
const { builtAt: _builtAt, ...hashedInputs } = input;
|
|
50
50
|
const version = (0, node_crypto.createHash)("sha256").update(stableStringify(hashedInputs)).digest("hex").slice(0, 16);
|
|
51
51
|
return WorkspaceVersionManifestSchema.parse({
|
|
52
52
|
...input,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version-manifest.cjs","names":["z","createHash"],"sources":["../src/version-manifest.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { z } from \"zod\";\n\n/**\n * WorkspaceVersionManifest — the immutable per-deploy document at\n * `bundles/<account>/<gateway>/<workspace>/versions/<version>.json`\n * (ADR 0020, as amended; atomic-deploys MAP decision 1). The published\n * config's slot pins this document via its `pin` (`manifest` + the\n * manifest's own SRI); every artifact coordinate lives here, so the config\n * stops growing with artifact kinds and old versions stay fully servable.\n */\n\nconst SRI = z.string().regex(/^sha384-[A-Za-z0-9+/=]+$/);\n\nexport const WorkspaceVersionManifestSchema = z.object({\n version: z.string().regex(/^[0-9a-f]{16}$/),\n builtAt: z.string().optional(),\n gitSha: z.string().optional(),\n entry: z.string().min(1),\n entryIntegrity: SRI,\n ssr: z\n .object({\n entry: z.string().min(1),\n integrity: SRI,\n })\n .optional(),\n browserManifest: z\n .object({\n file: z.string().min(1),\n integrity: SRI,\n })\n .optional(),\n /** extra assets (css, icons) — logical name → served-object SRI */\n assets: z.record(z.string(), SRI).optional(),\n /** shared-dependency versions this build was built against */\n shared: z.record(z.string(), z.string()).optional(),\n /**\n * Full per-file digest map of the dist (object path → served-object SRI).\n * Written by `every-plugin`-based deploys so the next deploy can diff against\n * it and skip re-uploading unchanged files; readers that predate the field\n * ignore it (zod strips unknown keys). Participates in the version hash.\n */\n files: z.record(z.string(), SRI).optional(),\n});\nexport type WorkspaceVersionManifest = z.infer<typeof WorkspaceVersionManifestSchema>;\n\nexport interface VersionManifestInput {\n /** Omit: a per-build timestamp makes the same version id map to different\n * manifest bytes per machine, breaking the pin's SRI against the image's\n * staged copy and the CDN's immutability for republished versions. */\n builtAt?: string;\n gitSha?: string;\n entry: string;\n entryIntegrity: string;\n ssr?: { entry: string; integrity: string };\n browserManifest?: { file: string; integrity: string };\n assets?: Record<string, string>;\n shared?: Record<string, string>;\n files?: Record<string, string>;\n}\n\n/**\n * Compose the manifest with its `version` derived from the canonical content\n * of the artifact coordinates alone (key-sorted, `builtAt` excluded) —\n * identical bytes → identical version id regardless of when they were built,\n * so republishing unchanged content is a pointer no-op. Any changed\n * coordinate → a new version (and a new file).\n */\nexport function composeVersionManifest(input: VersionManifestInput): WorkspaceVersionManifest {\n const { builtAt, ...hashedInputs } = input;\n const version = createHash(\"sha256\")\n .update(stableStringify(hashedInputs))\n .digest(\"hex\")\n .slice(0, 16);\n return WorkspaceVersionManifestSchema.parse({ ...input, version });\n}\n\nfunction stableStringify(value: unknown): string {\n if (Array.isArray(value)) return `[${value.map(stableStringify).join(\",\")}]`;\n if (value && typeof value === \"object\") {\n return `{${Object.entries(value)\n .filter(([, v]) => v !== undefined)\n .map(([k, v]) => `${JSON.stringify(k)}:${stableStringify(v)}`)\n .sort()\n .join(\",\")}}`;\n }\n return JSON.stringify(value) ?? \"null\";\n}\n"],"mappings":";;;;;;;;;;;;;AAYA,MAAM,MAAMA,MAAE,OAAO,CAAC,CAAC,MAAM,0BAA0B;AAEvD,MAAa,iCAAiCA,MAAE,OAAO;CACrD,SAASA,MAAE,OAAO,CAAC,CAAC,MAAM,gBAAgB;CAC1C,SAASA,MAAE,OAAO,CAAC,CAAC,SAAS;CAC7B,QAAQA,MAAE,OAAO,CAAC,CAAC,SAAS;CAC5B,OAAOA,MAAE,OAAO,CAAC,CAAC,IAAI,CAAC;CACvB,gBAAgB;CAChB,KAAKA,MACF,OAAO;EACN,OAAOA,MAAE,OAAO,CAAC,CAAC,IAAI,CAAC;EACvB,WAAW;CACb,CAAC,CAAC,CACD,SAAS;CACZ,iBAAiBA,MACd,OAAO;EACN,MAAMA,MAAE,OAAO,CAAC,CAAC,IAAI,CAAC;EACtB,WAAW;CACb,CAAC,CAAC,CACD,SAAS;;CAEZ,QAAQA,MAAE,OAAOA,MAAE,OAAO,GAAG,GAAG,CAAC,CAAC,SAAS;;CAE3C,QAAQA,MAAE,OAAOA,MAAE,OAAO,GAAGA,MAAE,OAAO,CAAC,CAAC,CAAC,SAAS;;;;;;;CAOlD,OAAOA,MAAE,OAAOA,MAAE,OAAO,GAAG,GAAG,CAAC,CAAC,SAAS;AAC5C,CAAC;;;;;;;;AAyBD,SAAgB,uBAAuB,OAAuD;CAC5F,MAAM,EAAE,SAAS,GAAG,iBAAiB;
|
|
1
|
+
{"version":3,"file":"version-manifest.cjs","names":["z","createHash"],"sources":["../src/version-manifest.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { z } from \"zod\";\n\n/**\n * WorkspaceVersionManifest — the immutable per-deploy document at\n * `bundles/<account>/<gateway>/<workspace>/versions/<version>.json`\n * (ADR 0020, as amended; atomic-deploys MAP decision 1). The published\n * config's slot pins this document via its `pin` (`manifest` + the\n * manifest's own SRI); every artifact coordinate lives here, so the config\n * stops growing with artifact kinds and old versions stay fully servable.\n */\n\nconst SRI = z.string().regex(/^sha384-[A-Za-z0-9+/=]+$/);\n\nexport const WorkspaceVersionManifestSchema = z.object({\n version: z.string().regex(/^[0-9a-f]{16}$/),\n builtAt: z.string().optional(),\n gitSha: z.string().optional(),\n entry: z.string().min(1),\n entryIntegrity: SRI,\n ssr: z\n .object({\n entry: z.string().min(1),\n integrity: SRI,\n })\n .optional(),\n browserManifest: z\n .object({\n file: z.string().min(1),\n integrity: SRI,\n })\n .optional(),\n /** extra assets (css, icons) — logical name → served-object SRI */\n assets: z.record(z.string(), SRI).optional(),\n /** shared-dependency versions this build was built against */\n shared: z.record(z.string(), z.string()).optional(),\n /**\n * Full per-file digest map of the dist (object path → served-object SRI).\n * Written by `every-plugin`-based deploys so the next deploy can diff against\n * it and skip re-uploading unchanged files; readers that predate the field\n * ignore it (zod strips unknown keys). Participates in the version hash.\n */\n files: z.record(z.string(), SRI).optional(),\n});\nexport type WorkspaceVersionManifest = z.infer<typeof WorkspaceVersionManifestSchema>;\n\nexport interface VersionManifestInput {\n /** Omit: a per-build timestamp makes the same version id map to different\n * manifest bytes per machine, breaking the pin's SRI against the image's\n * staged copy and the CDN's immutability for republished versions. */\n builtAt?: string;\n gitSha?: string;\n entry: string;\n entryIntegrity: string;\n ssr?: { entry: string; integrity: string };\n browserManifest?: { file: string; integrity: string };\n assets?: Record<string, string>;\n shared?: Record<string, string>;\n files?: Record<string, string>;\n}\n\n/**\n * Compose the manifest with its `version` derived from the canonical content\n * of the artifact coordinates alone (key-sorted, `builtAt` excluded) —\n * identical bytes → identical version id regardless of when they were built,\n * so republishing unchanged content is a pointer no-op. Any changed\n * coordinate → a new version (and a new file).\n */\nexport function composeVersionManifest(input: VersionManifestInput): WorkspaceVersionManifest {\n const { builtAt: _builtAt, ...hashedInputs } = input;\n const version = createHash(\"sha256\")\n .update(stableStringify(hashedInputs))\n .digest(\"hex\")\n .slice(0, 16);\n return WorkspaceVersionManifestSchema.parse({ ...input, version });\n}\n\nfunction stableStringify(value: unknown): string {\n if (Array.isArray(value)) return `[${value.map(stableStringify).join(\",\")}]`;\n if (value && typeof value === \"object\") {\n return `{${Object.entries(value)\n .filter(([, v]) => v !== undefined)\n .map(([k, v]) => `${JSON.stringify(k)}:${stableStringify(v)}`)\n .sort()\n .join(\",\")}}`;\n }\n return JSON.stringify(value) ?? \"null\";\n}\n"],"mappings":";;;;;;;;;;;;;AAYA,MAAM,MAAMA,MAAE,OAAO,CAAC,CAAC,MAAM,0BAA0B;AAEvD,MAAa,iCAAiCA,MAAE,OAAO;CACrD,SAASA,MAAE,OAAO,CAAC,CAAC,MAAM,gBAAgB;CAC1C,SAASA,MAAE,OAAO,CAAC,CAAC,SAAS;CAC7B,QAAQA,MAAE,OAAO,CAAC,CAAC,SAAS;CAC5B,OAAOA,MAAE,OAAO,CAAC,CAAC,IAAI,CAAC;CACvB,gBAAgB;CAChB,KAAKA,MACF,OAAO;EACN,OAAOA,MAAE,OAAO,CAAC,CAAC,IAAI,CAAC;EACvB,WAAW;CACb,CAAC,CAAC,CACD,SAAS;CACZ,iBAAiBA,MACd,OAAO;EACN,MAAMA,MAAE,OAAO,CAAC,CAAC,IAAI,CAAC;EACtB,WAAW;CACb,CAAC,CAAC,CACD,SAAS;;CAEZ,QAAQA,MAAE,OAAOA,MAAE,OAAO,GAAG,GAAG,CAAC,CAAC,SAAS;;CAE3C,QAAQA,MAAE,OAAOA,MAAE,OAAO,GAAGA,MAAE,OAAO,CAAC,CAAC,CAAC,SAAS;;;;;;;CAOlD,OAAOA,MAAE,OAAOA,MAAE,OAAO,GAAG,GAAG,CAAC,CAAC,SAAS;AAC5C,CAAC;;;;;;;;AAyBD,SAAgB,uBAAuB,OAAuD;CAC5F,MAAM,EAAE,SAAS,UAAU,GAAG,iBAAiB;CAC/C,MAAM,cAAUC,wBAAW,QAAQ,CAAC,CACjC,OAAO,gBAAgB,YAAY,CAAC,CAAC,CACrC,OAAO,KAAK,CAAC,CACb,MAAM,GAAG,EAAE;CACd,OAAO,+BAA+B,MAAM;EAAE,GAAG;EAAO;CAAQ,CAAC;AACnE;AAEA,SAAS,gBAAgB,OAAwB;CAC/C,IAAI,MAAM,QAAQ,KAAK,GAAG,OAAO,IAAI,MAAM,IAAI,eAAe,CAAC,CAAC,KAAK,GAAG,EAAE;CAC1E,IAAI,SAAS,OAAO,UAAU,UAC5B,OAAO,IAAI,OAAO,QAAQ,KAAK,CAAC,CAC7B,QAAQ,GAAG,OAAO,MAAM,MAAS,CAAC,CAClC,KAAK,CAAC,GAAG,OAAO,GAAG,KAAK,UAAU,CAAC,EAAE,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAC7D,KAAK,CAAC,CACN,KAAK,GAAG,EAAE;CAEf,OAAO,KAAK,UAAU,KAAK,KAAK;AAClC"}
|
|
@@ -45,7 +45,7 @@ const WorkspaceVersionManifestSchema = z.object({
|
|
|
45
45
|
* coordinate → a new version (and a new file).
|
|
46
46
|
*/
|
|
47
47
|
function composeVersionManifest(input) {
|
|
48
|
-
const { builtAt, ...hashedInputs } = input;
|
|
48
|
+
const { builtAt: _builtAt, ...hashedInputs } = input;
|
|
49
49
|
const version = createHash("sha256").update(stableStringify(hashedInputs)).digest("hex").slice(0, 16);
|
|
50
50
|
return WorkspaceVersionManifestSchema.parse({
|
|
51
51
|
...input,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version-manifest.mjs","names":[],"sources":["../src/version-manifest.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { z } from \"zod\";\n\n/**\n * WorkspaceVersionManifest — the immutable per-deploy document at\n * `bundles/<account>/<gateway>/<workspace>/versions/<version>.json`\n * (ADR 0020, as amended; atomic-deploys MAP decision 1). The published\n * config's slot pins this document via its `pin` (`manifest` + the\n * manifest's own SRI); every artifact coordinate lives here, so the config\n * stops growing with artifact kinds and old versions stay fully servable.\n */\n\nconst SRI = z.string().regex(/^sha384-[A-Za-z0-9+/=]+$/);\n\nexport const WorkspaceVersionManifestSchema = z.object({\n version: z.string().regex(/^[0-9a-f]{16}$/),\n builtAt: z.string().optional(),\n gitSha: z.string().optional(),\n entry: z.string().min(1),\n entryIntegrity: SRI,\n ssr: z\n .object({\n entry: z.string().min(1),\n integrity: SRI,\n })\n .optional(),\n browserManifest: z\n .object({\n file: z.string().min(1),\n integrity: SRI,\n })\n .optional(),\n /** extra assets (css, icons) — logical name → served-object SRI */\n assets: z.record(z.string(), SRI).optional(),\n /** shared-dependency versions this build was built against */\n shared: z.record(z.string(), z.string()).optional(),\n /**\n * Full per-file digest map of the dist (object path → served-object SRI).\n * Written by `every-plugin`-based deploys so the next deploy can diff against\n * it and skip re-uploading unchanged files; readers that predate the field\n * ignore it (zod strips unknown keys). Participates in the version hash.\n */\n files: z.record(z.string(), SRI).optional(),\n});\nexport type WorkspaceVersionManifest = z.infer<typeof WorkspaceVersionManifestSchema>;\n\nexport interface VersionManifestInput {\n /** Omit: a per-build timestamp makes the same version id map to different\n * manifest bytes per machine, breaking the pin's SRI against the image's\n * staged copy and the CDN's immutability for republished versions. */\n builtAt?: string;\n gitSha?: string;\n entry: string;\n entryIntegrity: string;\n ssr?: { entry: string; integrity: string };\n browserManifest?: { file: string; integrity: string };\n assets?: Record<string, string>;\n shared?: Record<string, string>;\n files?: Record<string, string>;\n}\n\n/**\n * Compose the manifest with its `version` derived from the canonical content\n * of the artifact coordinates alone (key-sorted, `builtAt` excluded) —\n * identical bytes → identical version id regardless of when they were built,\n * so republishing unchanged content is a pointer no-op. Any changed\n * coordinate → a new version (and a new file).\n */\nexport function composeVersionManifest(input: VersionManifestInput): WorkspaceVersionManifest {\n const { builtAt, ...hashedInputs } = input;\n const version = createHash(\"sha256\")\n .update(stableStringify(hashedInputs))\n .digest(\"hex\")\n .slice(0, 16);\n return WorkspaceVersionManifestSchema.parse({ ...input, version });\n}\n\nfunction stableStringify(value: unknown): string {\n if (Array.isArray(value)) return `[${value.map(stableStringify).join(\",\")}]`;\n if (value && typeof value === \"object\") {\n return `{${Object.entries(value)\n .filter(([, v]) => v !== undefined)\n .map(([k, v]) => `${JSON.stringify(k)}:${stableStringify(v)}`)\n .sort()\n .join(\",\")}}`;\n }\n return JSON.stringify(value) ?? \"null\";\n}\n"],"mappings":";;;;;;;;;;;;AAYA,MAAM,MAAM,EAAE,OAAO,CAAC,CAAC,MAAM,0BAA0B;AAEvD,MAAa,iCAAiC,EAAE,OAAO;CACrD,SAAS,EAAE,OAAO,CAAC,CAAC,MAAM,gBAAgB;CAC1C,SAAS,EAAE,OAAO,CAAC,CAAC,SAAS;CAC7B,QAAQ,EAAE,OAAO,CAAC,CAAC,SAAS;CAC5B,OAAO,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC;CACvB,gBAAgB;CAChB,KAAK,EACF,OAAO;EACN,OAAO,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC;EACvB,WAAW;CACb,CAAC,CAAC,CACD,SAAS;CACZ,iBAAiB,EACd,OAAO;EACN,MAAM,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC;EACtB,WAAW;CACb,CAAC,CAAC,CACD,SAAS;;CAEZ,QAAQ,EAAE,OAAO,EAAE,OAAO,GAAG,GAAG,CAAC,CAAC,SAAS;;CAE3C,QAAQ,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS;;;;;;;CAOlD,OAAO,EAAE,OAAO,EAAE,OAAO,GAAG,GAAG,CAAC,CAAC,SAAS;AAC5C,CAAC;;;;;;;;AAyBD,SAAgB,uBAAuB,OAAuD;CAC5F,MAAM,EAAE,SAAS,GAAG,iBAAiB;
|
|
1
|
+
{"version":3,"file":"version-manifest.mjs","names":[],"sources":["../src/version-manifest.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { z } from \"zod\";\n\n/**\n * WorkspaceVersionManifest — the immutable per-deploy document at\n * `bundles/<account>/<gateway>/<workspace>/versions/<version>.json`\n * (ADR 0020, as amended; atomic-deploys MAP decision 1). The published\n * config's slot pins this document via its `pin` (`manifest` + the\n * manifest's own SRI); every artifact coordinate lives here, so the config\n * stops growing with artifact kinds and old versions stay fully servable.\n */\n\nconst SRI = z.string().regex(/^sha384-[A-Za-z0-9+/=]+$/);\n\nexport const WorkspaceVersionManifestSchema = z.object({\n version: z.string().regex(/^[0-9a-f]{16}$/),\n builtAt: z.string().optional(),\n gitSha: z.string().optional(),\n entry: z.string().min(1),\n entryIntegrity: SRI,\n ssr: z\n .object({\n entry: z.string().min(1),\n integrity: SRI,\n })\n .optional(),\n browserManifest: z\n .object({\n file: z.string().min(1),\n integrity: SRI,\n })\n .optional(),\n /** extra assets (css, icons) — logical name → served-object SRI */\n assets: z.record(z.string(), SRI).optional(),\n /** shared-dependency versions this build was built against */\n shared: z.record(z.string(), z.string()).optional(),\n /**\n * Full per-file digest map of the dist (object path → served-object SRI).\n * Written by `every-plugin`-based deploys so the next deploy can diff against\n * it and skip re-uploading unchanged files; readers that predate the field\n * ignore it (zod strips unknown keys). Participates in the version hash.\n */\n files: z.record(z.string(), SRI).optional(),\n});\nexport type WorkspaceVersionManifest = z.infer<typeof WorkspaceVersionManifestSchema>;\n\nexport interface VersionManifestInput {\n /** Omit: a per-build timestamp makes the same version id map to different\n * manifest bytes per machine, breaking the pin's SRI against the image's\n * staged copy and the CDN's immutability for republished versions. */\n builtAt?: string;\n gitSha?: string;\n entry: string;\n entryIntegrity: string;\n ssr?: { entry: string; integrity: string };\n browserManifest?: { file: string; integrity: string };\n assets?: Record<string, string>;\n shared?: Record<string, string>;\n files?: Record<string, string>;\n}\n\n/**\n * Compose the manifest with its `version` derived from the canonical content\n * of the artifact coordinates alone (key-sorted, `builtAt` excluded) —\n * identical bytes → identical version id regardless of when they were built,\n * so republishing unchanged content is a pointer no-op. Any changed\n * coordinate → a new version (and a new file).\n */\nexport function composeVersionManifest(input: VersionManifestInput): WorkspaceVersionManifest {\n const { builtAt: _builtAt, ...hashedInputs } = input;\n const version = createHash(\"sha256\")\n .update(stableStringify(hashedInputs))\n .digest(\"hex\")\n .slice(0, 16);\n return WorkspaceVersionManifestSchema.parse({ ...input, version });\n}\n\nfunction stableStringify(value: unknown): string {\n if (Array.isArray(value)) return `[${value.map(stableStringify).join(\",\")}]`;\n if (value && typeof value === \"object\") {\n return `{${Object.entries(value)\n .filter(([, v]) => v !== undefined)\n .map(([k, v]) => `${JSON.stringify(k)}:${stableStringify(v)}`)\n .sort()\n .join(\",\")}}`;\n }\n return JSON.stringify(value) ?? \"null\";\n}\n"],"mappings":";;;;;;;;;;;;AAYA,MAAM,MAAM,EAAE,OAAO,CAAC,CAAC,MAAM,0BAA0B;AAEvD,MAAa,iCAAiC,EAAE,OAAO;CACrD,SAAS,EAAE,OAAO,CAAC,CAAC,MAAM,gBAAgB;CAC1C,SAAS,EAAE,OAAO,CAAC,CAAC,SAAS;CAC7B,QAAQ,EAAE,OAAO,CAAC,CAAC,SAAS;CAC5B,OAAO,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC;CACvB,gBAAgB;CAChB,KAAK,EACF,OAAO;EACN,OAAO,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC;EACvB,WAAW;CACb,CAAC,CAAC,CACD,SAAS;CACZ,iBAAiB,EACd,OAAO;EACN,MAAM,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC;EACtB,WAAW;CACb,CAAC,CAAC,CACD,SAAS;;CAEZ,QAAQ,EAAE,OAAO,EAAE,OAAO,GAAG,GAAG,CAAC,CAAC,SAAS;;CAE3C,QAAQ,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS;;;;;;;CAOlD,OAAO,EAAE,OAAO,EAAE,OAAO,GAAG,GAAG,CAAC,CAAC,SAAS;AAC5C,CAAC;;;;;;;;AAyBD,SAAgB,uBAAuB,OAAuD;CAC5F,MAAM,EAAE,SAAS,UAAU,GAAG,iBAAiB;CAC/C,MAAM,UAAU,WAAW,QAAQ,CAAC,CACjC,OAAO,gBAAgB,YAAY,CAAC,CAAC,CACrC,OAAO,KAAK,CAAC,CACb,MAAM,GAAG,EAAE;CACd,OAAO,+BAA+B,MAAM;EAAE,GAAG;EAAO;CAAQ,CAAC;AACnE;AAEA,SAAS,gBAAgB,OAAwB;CAC/C,IAAI,MAAM,QAAQ,KAAK,GAAG,OAAO,IAAI,MAAM,IAAI,eAAe,CAAC,CAAC,KAAK,GAAG,EAAE;CAC1E,IAAI,SAAS,OAAO,UAAU,UAC5B,OAAO,IAAI,OAAO,QAAQ,KAAK,CAAC,CAC7B,QAAQ,GAAG,OAAO,MAAM,MAAS,CAAC,CAClC,KAAK,CAAC,GAAG,OAAO,GAAG,KAAK,UAAU,CAAC,EAAE,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAC7D,KAAK,CAAC,CACN,KAAK,GAAG,EAAE;CAEf,OAAO,KAAK,UAAU,KAAK,KAAK;AAClC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "every-plugin",
|
|
3
|
-
"version": "3.0.0-rc.
|
|
3
|
+
"version": "3.0.0-rc.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -18,6 +18,14 @@
|
|
|
18
18
|
"import": "./dist/index.mjs",
|
|
19
19
|
"require": "./dist/index.cjs"
|
|
20
20
|
},
|
|
21
|
+
"./client": {
|
|
22
|
+
"bun": {
|
|
23
|
+
"types": "./src/client.ts",
|
|
24
|
+
"import": "./src/client.ts"
|
|
25
|
+
},
|
|
26
|
+
"types": "./dist/client.d.mts",
|
|
27
|
+
"import": "./dist/client.mjs"
|
|
28
|
+
},
|
|
21
29
|
"./identity": {
|
|
22
30
|
"bun": {
|
|
23
31
|
"types": "./src/identity.ts",
|
|
@@ -144,6 +152,14 @@
|
|
|
144
152
|
"import": "./dist/build/ui/index.mjs",
|
|
145
153
|
"require": "./dist/build/ui/index.cjs"
|
|
146
154
|
},
|
|
155
|
+
"./dev-host": {
|
|
156
|
+
"bun": {
|
|
157
|
+
"types": "./src/dev/host.ts",
|
|
158
|
+
"import": "./src/dev/host.ts"
|
|
159
|
+
},
|
|
160
|
+
"types": "./dist/dev/host.d.mts",
|
|
161
|
+
"import": "./dist/dev/host.mjs"
|
|
162
|
+
},
|
|
147
163
|
"./dev-serve": {
|
|
148
164
|
"bun": {
|
|
149
165
|
"types": "./src/dev/serve.ts",
|
|
@@ -222,7 +238,8 @@
|
|
|
222
238
|
"@rsbuild/plugin-react": "2.1.0",
|
|
223
239
|
"@tanstack/router-generator": "1.167.33",
|
|
224
240
|
"@tanstack/router-plugin": "1.168.35",
|
|
225
|
-
"sirv": "3.0.2"
|
|
241
|
+
"sirv": "3.0.2",
|
|
242
|
+
"sonner": ">=2.0.0"
|
|
226
243
|
},
|
|
227
244
|
"keywords": [
|
|
228
245
|
"plugin",
|
package/src/client.ts
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { createORPCClient, onError } from "@orpc/client";
|
|
2
|
+
import { RPCLink } from "@orpc/client/fetch";
|
|
3
|
+
import type { ContractRouterClient, RouterContract } from "@orpc/contract";
|
|
4
|
+
|
|
5
|
+
export type RpcConnectionErrorCopy = () => { title: string; description: string };
|
|
6
|
+
|
|
7
|
+
export interface RpcClientConfig {
|
|
8
|
+
hostUrl: string;
|
|
9
|
+
path: `/${string}`;
|
|
10
|
+
connectionError?: RpcConnectionErrorCopy;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const RATE_LIMIT_MAX_RETRIES = 3;
|
|
14
|
+
const RATE_LIMIT_RETRY_CAP_MS = 2_000;
|
|
15
|
+
const browserClients = new Map<string, unknown>();
|
|
16
|
+
type FetchInput = Parameters<typeof fetch>[0];
|
|
17
|
+
|
|
18
|
+
async function fetchWithRateLimitRetry(
|
|
19
|
+
fetchUrl: FetchInput,
|
|
20
|
+
options?: RequestInit,
|
|
21
|
+
): Promise<Response> {
|
|
22
|
+
let response = await fetch(fetchUrl, options);
|
|
23
|
+
for (let attempt = 1; attempt <= RATE_LIMIT_MAX_RETRIES && response.status === 429; attempt++) {
|
|
24
|
+
const retryAfterSeconds = Number(response.headers.get("retry-after"));
|
|
25
|
+
const delay =
|
|
26
|
+
Number.isFinite(retryAfterSeconds) && retryAfterSeconds > 0
|
|
27
|
+
? Math.min(retryAfterSeconds * 1000, RATE_LIMIT_RETRY_CAP_MS)
|
|
28
|
+
: 100 * attempt;
|
|
29
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
30
|
+
response = await fetch(fetchUrl, options);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return response;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function createRpcLink(config: RpcClientConfig, headers?: Headers) {
|
|
37
|
+
return new RPCLink({
|
|
38
|
+
origin: config.hostUrl,
|
|
39
|
+
url: config.path,
|
|
40
|
+
interceptors: [
|
|
41
|
+
onError((error: unknown) => {
|
|
42
|
+
const browserWindow = (globalThis as { window?: unknown }).window;
|
|
43
|
+
if (typeof browserWindow === "undefined") {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (error && typeof error === "object" && "message" in error) {
|
|
48
|
+
const message = String(error.message).toLowerCase();
|
|
49
|
+
if (
|
|
50
|
+
message.includes("fetch") ||
|
|
51
|
+
message.includes("network") ||
|
|
52
|
+
message.includes("failed to fetch")
|
|
53
|
+
) {
|
|
54
|
+
void import("sonner")
|
|
55
|
+
.then(({ toast }) => {
|
|
56
|
+
const message = config.connectionError?.() ?? {
|
|
57
|
+
title: "Unable to connect to API",
|
|
58
|
+
description: "The API is currently unavailable. Please try again later.",
|
|
59
|
+
};
|
|
60
|
+
toast.error(message.title, {
|
|
61
|
+
id: "api-connection-error",
|
|
62
|
+
description: message.description,
|
|
63
|
+
});
|
|
64
|
+
})
|
|
65
|
+
.catch(() => {});
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}),
|
|
69
|
+
],
|
|
70
|
+
fetch(fetchUrl: FetchInput, options?: RequestInit) {
|
|
71
|
+
return fetchWithRateLimitRetry(fetchUrl, {
|
|
72
|
+
...options,
|
|
73
|
+
credentials: "include",
|
|
74
|
+
headers: headers
|
|
75
|
+
? { ...Object.fromEntries(headers), ...(options?.headers as Record<string, string>) }
|
|
76
|
+
: options?.headers,
|
|
77
|
+
});
|
|
78
|
+
},
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function buildRpcClient<T extends RouterContract>(
|
|
83
|
+
config: RpcClientConfig,
|
|
84
|
+
headers?: Headers,
|
|
85
|
+
): ContractRouterClient<T> {
|
|
86
|
+
if (!config.hostUrl) {
|
|
87
|
+
throw new Error("Missing runtime host URL");
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return createORPCClient(createRpcLink(config, headers)) as ContractRouterClient<T>;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export function createRpcClient<T extends RouterContract = RouterContract>(
|
|
94
|
+
config: RpcClientConfig,
|
|
95
|
+
headers?: Headers,
|
|
96
|
+
): ContractRouterClient<T> {
|
|
97
|
+
const browserWindow = (globalThis as { window?: unknown }).window;
|
|
98
|
+
if (typeof browserWindow !== "undefined" && !headers) {
|
|
99
|
+
const key = `${config.hostUrl}${config.path}`;
|
|
100
|
+
const memoized = browserClients.get(key);
|
|
101
|
+
if (memoized) {
|
|
102
|
+
return memoized as ContractRouterClient<T>;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const client = buildRpcClient<T>(config, headers);
|
|
106
|
+
browserClients.set(key, client);
|
|
107
|
+
return client;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return buildRpcClient<T>(config, headers);
|
|
111
|
+
}
|