@jointhedots/gear 1.1.18 → 1.2.2

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.
Files changed (113) hide show
  1. package/esm/builder/build-app-bundle.d.ts +28 -0
  2. package/esm/builder/build-app-bundle.js +4 -7
  3. package/esm/builder/build-app-host.d.ts +28 -0
  4. package/esm/builder/build-app-host.js +0 -1
  5. package/esm/builder/build-application.d.ts +47 -0
  6. package/esm/builder/build-application.js +3 -5
  7. package/esm/builder/build-library.d.ts +20 -0
  8. package/esm/builder/build-library.js +1 -2
  9. package/esm/builder/build-target.d.ts +27 -0
  10. package/esm/builder/build-target.js +3 -4
  11. package/esm/builder/helpers/emit-bundle-manifest.d.ts +9 -0
  12. package/esm/builder/helpers/emit-bundle-manifest.js +1 -2
  13. package/esm/builder/helpers/emit-components-dts.d.ts +9 -0
  14. package/esm/builder/helpers/emit-components-dts.js +1 -2
  15. package/esm/builder/helpers/emit-esmodules.d.ts +61 -0
  16. package/esm/builder/helpers/emit-esmodules.js +5 -6
  17. package/esm/builder/helpers/emit-package-manifest.d.ts +9 -0
  18. package/esm/builder/helpers/emit-package-manifest.js +0 -1
  19. package/esm/builder/helpers/emit-static-assets.d.ts +14 -0
  20. package/esm/builder/helpers/emit-static-assets.js +1 -2
  21. package/esm/builder/helpers/emit-typescript-definition.d.ts +35 -0
  22. package/esm/builder/helpers/emit-typescript-definition.js +6 -7
  23. package/esm/builder/helpers/path-helpers.d.ts +9 -0
  24. package/esm/builder/helpers/path-helpers.js +0 -1
  25. package/esm/builder/helpers/task.d.ts +8 -0
  26. package/esm/builder/helpers/task.js +0 -1
  27. package/esm/cli.d.ts +2 -0
  28. package/esm/cli.js +1 -4
  29. package/esm/commands/init.d.ts +2 -0
  30. package/esm/commands/init.js +0 -1
  31. package/esm/commands/install.d.ts +5 -0
  32. package/esm/commands/install.js +4 -5
  33. package/esm/commands/make.d.ts +16 -0
  34. package/esm/commands/make.js +5 -5
  35. package/esm/commands/run.d.ts +8 -0
  36. package/esm/commands/run.js +6 -7
  37. package/esm/commands/serve.d.ts +9 -0
  38. package/esm/commands/serve.js +3 -4
  39. package/esm/core/commands/interface.d.ts +26 -0
  40. package/esm/core/commands/interface.js +21 -0
  41. package/esm/core/components/components.d.ts +73 -0
  42. package/esm/core/components/components.js +2 -0
  43. package/esm/core/components/helpers.d.ts +7 -0
  44. package/esm/core/components/helpers.js +68 -0
  45. package/esm/core/components/manifold.d.ts +77 -0
  46. package/esm/core/components/manifold.js +442 -0
  47. package/esm/core/components/mod.d.ts +4 -0
  48. package/esm/core/components/mod.js +4 -0
  49. package/esm/core/components/provider.d.ts +42 -0
  50. package/esm/core/components/provider.js +127 -0
  51. package/esm/core/logging/mod.d.ts +53 -0
  52. package/esm/core/logging/mod.js +142 -0
  53. package/esm/core/logging/trace.d.ts +51 -0
  54. package/esm/core/logging/trace.js +17 -0
  55. package/esm/core/mod-browser.d.ts +1 -0
  56. package/esm/core/mod-browser.js +1 -0
  57. package/esm/core/mod-node.d.ts +1 -0
  58. package/esm/core/mod-node.js +1 -0
  59. package/esm/core/mod.d.ts +5 -0
  60. package/esm/core/mod.js +5 -0
  61. package/esm/core/schema/helpers.d.ts +36 -0
  62. package/esm/core/schema/helpers.js +163 -0
  63. package/esm/core/schema/mod.d.ts +3 -0
  64. package/esm/core/schema/mod.js +3 -0
  65. package/esm/core/schema/schema.d.ts +376 -0
  66. package/esm/core/schema/schema.js +234 -0
  67. package/esm/core/schema/zod.d.ts +44 -0
  68. package/esm/core/schema/zod.js +127 -0
  69. package/esm/core/services/mod.d.ts +5 -0
  70. package/esm/core/services/mod.js +5 -0
  71. package/esm/core/services/service-accessor.d.ts +17 -0
  72. package/esm/core/services/service-accessor.js +20 -0
  73. package/esm/core/services/service-definitions.d.ts +37 -0
  74. package/esm/core/services/service-definitions.js +44 -0
  75. package/esm/core/services/service-points.d.ts +40 -0
  76. package/esm/core/services/service-points.js +164 -0
  77. package/esm/core/services/service-specification.d.ts +52 -0
  78. package/esm/core/services/service-specification.js +59 -0
  79. package/esm/core/services/settings.d.ts +29 -0
  80. package/esm/core/services/settings.js +123 -0
  81. package/esm/utils/file.d.ts +39 -0
  82. package/esm/utils/file.js +3 -4
  83. package/esm/utils/graph-ordering.d.ts +21 -0
  84. package/esm/utils/graph-ordering.js +0 -1
  85. package/esm/utils/normalized-name.d.ts +17 -0
  86. package/esm/utils/normalized-name.js +0 -1
  87. package/esm/workspace/component.d.ts +70 -0
  88. package/esm/workspace/component.js +0 -1
  89. package/esm/workspace/helpers/config-loader.d.ts +37 -0
  90. package/esm/workspace/helpers/config-loader.js +4 -5
  91. package/esm/workspace/helpers/create-manifests.d.ts +13 -0
  92. package/esm/workspace/helpers/create-manifests.js +1 -2
  93. package/esm/workspace/helpers/discover-workspace.d.ts +4 -0
  94. package/esm/workspace/helpers/discover-workspace.js +130 -134
  95. package/esm/workspace/helpers/lockfile.d.ts +5 -0
  96. package/esm/workspace/helpers/lockfile.js +0 -1
  97. package/esm/workspace/helpers/logger.d.ts +65 -0
  98. package/esm/workspace/helpers/logger.js +0 -1
  99. package/esm/workspace/helpers/package-npm.d.ts +1 -0
  100. package/esm/workspace/helpers/package-npm.js +0 -1
  101. package/esm/workspace/mod.d.ts +1 -0
  102. package/esm/workspace/mod.js +1 -0
  103. package/esm/workspace/packager.d.ts +5 -0
  104. package/esm/workspace/packager.js +1 -2
  105. package/esm/workspace/packagers/packager-standard.d.ts +7 -0
  106. package/esm/workspace/packagers/packager-standard.js +48 -24
  107. package/esm/workspace/storage.d.ts +59 -0
  108. package/esm/workspace/storage.js +19 -15
  109. package/esm/workspace/workspace.d.ts +161 -0
  110. package/esm/workspace/workspace.js +25 -17
  111. package/package.json +25 -18
  112. package/esm/commands/publish.js +0 -36
  113. package/esm/publish/publish_aws_s3.js +0 -67
@@ -0,0 +1,127 @@
1
+ import { z } from "zod";
2
+ import {} from "./schema.js";
3
+ // =============================================================================
4
+ // ZodService - Service Reference Type (External Spec)
5
+ // =============================================================================
6
+ export class ZodService {
7
+ $spec;
8
+ version;
9
+ _type = "ZodService";
10
+ constructor($spec, version) {
11
+ this.$spec = $spec;
12
+ this.version = version;
13
+ }
14
+ parse(data) {
15
+ if (typeof data !== "object" || data === null)
16
+ throw new Error(`Expected object, received ${typeof data}`);
17
+ return data;
18
+ }
19
+ safeParse(data) {
20
+ try {
21
+ return { success: true, data: this.parse(data) };
22
+ }
23
+ catch (e) {
24
+ return { success: false, error: e };
25
+ }
26
+ }
27
+ toJSONSchema() {
28
+ return { type: "service", $spec: this.$spec, ...(this.version && { version: this.version }) };
29
+ }
30
+ static create($spec, version) { return new ZodService($spec, version); }
31
+ }
32
+ export const zService = ZodService.create;
33
+ // =============================================================================
34
+ // Zod → JSON Schema (using Zod 4 native toJSONSchema with custom override)
35
+ // =============================================================================
36
+ export function zodToJSONSchema(schema) {
37
+ if (schema instanceof ZodService)
38
+ return schema.toJSONSchema();
39
+ return z.toJSONSchema(schema, {
40
+ unrepresentable: "any",
41
+ override: ({ zodSchema, jsonSchema }) => {
42
+ // Handle ZodService wrapped in other types via metadata
43
+ const meta = zodSchema._zod?.def?.meta;
44
+ if (meta?.$spec) {
45
+ Object.assign(jsonSchema, meta.toServiceSchema());
46
+ }
47
+ }
48
+ });
49
+ }
50
+ // =============================================================================
51
+ // JSON Schema → Zod (using Zod 4 native fromJSONSchema)
52
+ // =============================================================================
53
+ export function jsonSchemaToZod(schema) {
54
+ if (!schema || !Object.keys(schema).length)
55
+ return z.any();
56
+ // Handle custom "service" type not supported by standard JSON Schema
57
+ if (schema.type === "service") {
58
+ const s = schema;
59
+ return zService(s.$spec, s.version);
60
+ }
61
+ return z.fromJSONSchema(schema);
62
+ }
63
+ export function validate(schema, data) {
64
+ const zs = schema instanceof z.ZodType ? schema : jsonSchemaToZod(schema);
65
+ const r = zs.safeParse(data);
66
+ return r.success
67
+ ? { success: true, data: r.data }
68
+ : { success: false, errors: r.error.issues.map(i => ({ path: i.path.map(String), message: i.message, code: i.code })) };
69
+ }
70
+ export function validateOrThrow(schema, data) {
71
+ const zs = schema instanceof z.ZodType ? schema : jsonSchemaToZod(schema);
72
+ return zs.parse(data);
73
+ }
74
+ export function generateTypeScript(schema, name, opts = {}) {
75
+ const { comments = true, indent = " ", export: exp = true } = opts;
76
+ const ex = exp ? "export " : "";
77
+ const desc = comments && schema.description ? `/** ${schema.description} */\n` : "";
78
+ if (schema.type === "service") {
79
+ const s = schema;
80
+ const specComment = comments ? `${indent}/** @spec ${s.$spec}${s.version ? ` @version ${s.version}` : ""} */\n` : "";
81
+ return `${desc}${ex}interface ${name} {\n${specComment}${indent}[key: string]: unknown\n}`;
82
+ }
83
+ return `${desc}${ex}type ${name} = ${toTS(schema, indent, 0)}`;
84
+ }
85
+ const toTS = (s, ind, d) => {
86
+ const base = ind.repeat(d), inner = ind.repeat(d + 1);
87
+ if (s.const !== undefined)
88
+ return JSON.stringify(s.const);
89
+ if (s.enum)
90
+ return s.enum.map(v => JSON.stringify(v)).join(" | ");
91
+ if (s.oneOf)
92
+ return s.oneOf.map(x => toTS(x, ind, d)).join(" | ");
93
+ if (s.anyOf)
94
+ return s.anyOf.map(x => toTS(x, ind, d)).join(" | ");
95
+ if (s.allOf)
96
+ return s.allOf.map(x => toTS(x, ind, d)).join(" & ");
97
+ switch (s.type) {
98
+ case "string": return "string";
99
+ case "number":
100
+ case "integer": return "number";
101
+ case "boolean": return "boolean";
102
+ case "null": return "null";
103
+ case "array":
104
+ if (Array.isArray(s.items))
105
+ return `[${s.items.map(i => toTS(i, ind, d)).join(", ")}]`;
106
+ return `${s.items ? toTS(s.items, ind, d) : "any"}[]`;
107
+ case "object":
108
+ if (!s.properties && s.additionalProperties && typeof s.additionalProperties === "object")
109
+ return `Record<string, ${toTS(s.additionalProperties, ind, d)}>`;
110
+ if (!s.properties)
111
+ return "object";
112
+ const req = s.required ?? [];
113
+ const props = Object.entries(s.properties).map(([k, v]) => `${inner}${k}${req.includes(k) ? "" : "?"}: ${toTS(v, ind, d + 1)}`);
114
+ if (typeof s.additionalProperties === "object" && Object.keys(s.additionalProperties).length)
115
+ props.push(`${inner}[key: string]: ${toTS(s.additionalProperties, ind, d + 1)}`);
116
+ return `{\n${props.join("\n")}\n${base}}`;
117
+ case "function": return "Function";
118
+ case "view":
119
+ case "display":
120
+ case "element": return "React.ReactNode";
121
+ default: return "any";
122
+ }
123
+ };
124
+ // =============================================================================
125
+ // Re-exports
126
+ // =============================================================================
127
+ export { z };
@@ -0,0 +1,5 @@
1
+ export * from "./service-definitions.ts";
2
+ export * from "./service-points.ts";
3
+ export * from "./service-specification.ts";
4
+ export * from "./service-accessor.ts";
5
+ export * from "./settings.ts";
@@ -0,0 +1,5 @@
1
+ export * from "./service-definitions.js";
2
+ export * from "./service-points.js";
3
+ export * from "./service-specification.js";
4
+ export * from "./service-accessor.js";
5
+ export * from "./settings.js";
@@ -0,0 +1,17 @@
1
+ import type { ComponentEntry } from "../components/manifold.ts";
2
+ export type ServiceType = string;
3
+ export declare class ServiceAccessor<Instance extends any, Spec extends any> {
4
+ resource: string;
5
+ definition: any;
6
+ private constructor();
7
+ /** Synchronously retrieves the service instance from the given component entry. Returns undefined if the resource is not available. */
8
+ get(entry: ComponentEntry): Instance;
9
+ /** Asynchronously fetches the service instance from the given component entry, waiting until the resource becomes available. */
10
+ fetch(entry: ComponentEntry): Promise<Instance>;
11
+ /** Returns the specification/configuration associated with this service from the given component entry. */
12
+ spec(entry: ComponentEntry): Spec;
13
+ /** Creates a child service accessor scoped under this service's resource path. */
14
+ subservice<T extends any>(name: string): ServiceAccessor<T, Spec>;
15
+ /** Factory method that creates a new ServiceAccessor for the given resource name and optional definition. */
16
+ static About<Instance extends any, Spec extends any>(resource: string, definition?: any): ServiceAccessor<Instance, Spec>;
17
+ }
@@ -0,0 +1,20 @@
1
+ export class ServiceAccessor {
2
+ resource;
3
+ definition;
4
+ constructor(resource, definition) {
5
+ this.resource = resource;
6
+ this.definition = definition;
7
+ }
8
+ /** Synchronously retrieves the service instance from the given component entry. Returns undefined if the resource is not available. */
9
+ get(entry) { return entry.getResource(this.resource)?.get(); }
10
+ /** Asynchronously fetches the service instance from the given component entry, waiting until the resource becomes available. */
11
+ fetch(entry) { return entry.fetchResource(this.resource); }
12
+ /** Returns the specification/configuration associated with this service from the given component entry. */
13
+ spec(entry) { return entry.acquireResource(this.resource)?.spec; }
14
+ /** Creates a child service accessor scoped under this service's resource path. */
15
+ subservice(name) { return ServiceAccessor.About(`${this.resource}.${name}`); }
16
+ /** Factory method that creates a new ServiceAccessor for the given resource name and optional definition. */
17
+ static About(resource, definition = null) {
18
+ return new ServiceAccessor(resource, definition);
19
+ }
20
+ }
@@ -0,0 +1,37 @@
1
+ import type { ServiceSchema } from "../schema/schema.ts";
2
+ import { ZodService } from "../schema/zod.ts";
3
+ import type { ZodType } from "zod";
4
+ import { type ServiceSpecification, type ServiceCompatibility } from "./service-specification.ts";
5
+ /**
6
+ * ServiceDefinition is a concrete definition linking a specification to implementation.
7
+ *
8
+ * @template I - The TypeScript interface type this service implements
9
+ * @template P - The type of properties (hyperparameters) for service speci alization
10
+ */
11
+ export interface ServiceDefinition<I, P = unknown> {
12
+ /** Reference to the service specification */
13
+ $spec: string;
14
+ /** Version of the specification this definition implements */
15
+ version: string;
16
+ /** Zod schema for validating properties */
17
+ properties?: ZodType<P>;
18
+ /** Check if the service is compatible for assignement with an other definition */
19
+ isAssignable(from: ServiceDefinition<I>): any;
20
+ }
21
+ export type ServiceInterface<T> = T extends ServiceDefinition<infer I, any> ? I : never;
22
+ /**
23
+ * Get ZodService type from a service definition
24
+ */
25
+ export declare function getServiceZod<I>(def: ServiceDefinition<I>): ZodService<I>;
26
+ /**
27
+ * Get ServiceSchema (JSON Schema representation) from a service definition
28
+ */
29
+ export declare function getServiceSchema<I, P>(def: ServiceDefinition<I, P>): ServiceSchema;
30
+ /**
31
+ * Get full ServiceSchema including attributes schema from a specification
32
+ */
33
+ export declare function getServiceSchemaFromSpec<I, A>(spec: ServiceSpecification<I, A>): ServiceSchema;
34
+ /**
35
+ * Check if a service definition matches a specification
36
+ */
37
+ export declare function matchesSpecification<I, A>(def: ServiceDefinition<I, A>, spec: ServiceSpecification<I, A>): ServiceCompatibility;
@@ -0,0 +1,44 @@
1
+ import { ZodService } from "../schema/zod.js";
2
+ import { checkVersionCompatibility } from "./service-specification.js";
3
+ // =============================================================================
4
+ // Service Factory Functions
5
+ // =============================================================================
6
+ /**
7
+ * Get ZodService type from a service definition
8
+ */
9
+ export function getServiceZod(def) {
10
+ return ZodService.create(def.$spec, def.version);
11
+ }
12
+ /**
13
+ * Get ServiceSchema (JSON Schema representation) from a service definition
14
+ */
15
+ export function getServiceSchema(def) {
16
+ return {
17
+ type: "service",
18
+ $spec: def.$spec,
19
+ version: def.version,
20
+ };
21
+ }
22
+ /**
23
+ * Get full ServiceSchema including attributes schema from a specification
24
+ */
25
+ export function getServiceSchemaFromSpec(spec) {
26
+ const schema = {
27
+ type: "service",
28
+ $spec: spec.$spec,
29
+ version: spec.version,
30
+ };
31
+ return schema;
32
+ }
33
+ /**
34
+ * Check if a service definition matches a specification
35
+ */
36
+ export function matchesSpecification(def, spec) {
37
+ if (def.$spec !== spec.$spec) {
38
+ return {
39
+ compatible: false,
40
+ reason: `Specification mismatch: definition uses "${def.$spec}", expected "${spec.$spec}"`
41
+ };
42
+ }
43
+ return checkVersionCompatibility(spec.version, def.version, spec.minCompatibleVersion);
44
+ }
@@ -0,0 +1,40 @@
1
+ import { type ComponentID } from "../components/components.ts";
2
+ import { type ILogDispatcher, type LogObject } from "../logging/mod.ts";
3
+ import { ServiceAccessor, type ServiceType } from "./service-accessor.ts";
4
+ export declare const ServicePoints: Map<string, ServicePoint>;
5
+ export type ServicePointID = string;
6
+ export type ServicePointProperties = {
7
+ title?: string;
8
+ multiple?: boolean;
9
+ alternative?: ServicePointID;
10
+ };
11
+ export type ServicePointSetting = {
12
+ id: ServicePointID;
13
+ providers: ComponentID[];
14
+ properties: ServicePointProperties;
15
+ };
16
+ export type ServiceChangeHandler = (service: ServicePoint) => void;
17
+ export declare class ServicePoint<IService = unknown> implements ILogDispatcher {
18
+ descriptor: ServicePointSetting;
19
+ service: ServiceType;
20
+ name: string;
21
+ services: IService[];
22
+ loading: Promise<IService[]>;
23
+ ready: boolean;
24
+ failure: Error;
25
+ constructor(descriptor: ServicePointSetting);
26
+ get id(): string;
27
+ get multiple(): boolean;
28
+ fetch(): Promise<IService[]>;
29
+ reset(descriptor: ServicePointSetting): Promise<this>;
30
+ override(providers: ComponentID[]): void;
31
+ notifyError(error: Error): void;
32
+ notifyObject(object: LogObject): void;
33
+ }
34
+ export declare function listenServicePoints(handler: ServiceChangeHandler): ServiceChangeHandler;
35
+ export declare function unlistenServicePoints(handler: ServiceChangeHandler): void;
36
+ export declare function acquireServicePointDescriptor(id: string): ServicePointSetting;
37
+ export declare function updateServicePointDescriptor(id: string, properties: ServicePointProperties): ServicePointSetting;
38
+ export declare function getServicePoint<IService>(id: string): ServicePoint<IService>;
39
+ export declare function acquireServicePoint<IService>(id: string): ServicePoint<IService>;
40
+ export declare function createServicePoint<S extends any, D extends any>(service: ServiceAccessor<S, D>, name: ServicePointID, properties?: ServicePointProperties): ServicePoint<S>;
@@ -0,0 +1,164 @@
1
+ import { acquireComponent, ComponentsRegistry } from "../components/manifold.js";
2
+ import {} from "../components/components.js";
3
+ import { getSettings, listenSettings, WriteMode } from "./settings.js";
4
+ import { Log } from "../logging/mod.js";
5
+ import { ServiceAccessor } from "./service-accessor.js";
6
+ export const ServicePoints = new Map();
7
+ const ServiceChangeHandlers = new Set();
8
+ export class ServicePoint {
9
+ descriptor;
10
+ service = "";
11
+ name = "";
12
+ services = [];
13
+ loading = null;
14
+ ready = false;
15
+ failure = null;
16
+ constructor(descriptor) {
17
+ this.descriptor = descriptor;
18
+ const [service, name] = descriptor.id.split("/");
19
+ this.service = service;
20
+ this.name = name;
21
+ }
22
+ get id() {
23
+ return this.descriptor.id;
24
+ }
25
+ get multiple() {
26
+ return this.descriptor?.properties?.multiple || false;
27
+ }
28
+ async fetch() {
29
+ if (this.ready) {
30
+ return this.services;
31
+ }
32
+ if (!this.loading) {
33
+ this.loading = new Promise(async (resolve) => {
34
+ const { descriptor } = this;
35
+ const { providers } = this.descriptor;
36
+ const services = await fetchComponentsService(providers, this.service, this.id, this);
37
+ if (descriptor === this.descriptor) {
38
+ this.services = services;
39
+ this.ready = true;
40
+ this.loading = null;
41
+ resolve(this.services);
42
+ }
43
+ else {
44
+ resolve(this.fetch());
45
+ }
46
+ });
47
+ }
48
+ return this.loading;
49
+ }
50
+ async reset(descriptor) {
51
+ if (this.descriptor !== descriptor) {
52
+ this.descriptor = descriptor;
53
+ if (this.loading || this.ready || this.failure) {
54
+ this.failure = null;
55
+ this.loading = null;
56
+ this.ready = false;
57
+ ServiceChangeHandlers.forEach(l => l(this));
58
+ await this.fetch();
59
+ }
60
+ ServiceChangeHandlers.forEach(l => l(this));
61
+ }
62
+ return this;
63
+ }
64
+ override(providers) {
65
+ const settings = getSettings();
66
+ const descriptor = settings.get("service_points", this.id);
67
+ settings.set("service_points", this.id, { ...descriptor, providers }, WriteMode.Temporary);
68
+ }
69
+ notifyError(error) {
70
+ this.failure = error;
71
+ Log.error(error);
72
+ }
73
+ notifyObject(object) {
74
+ Log.send(object);
75
+ }
76
+ }
77
+ export function listenServicePoints(handler) {
78
+ ServiceChangeHandlers.add(handler);
79
+ return handler;
80
+ }
81
+ export function unlistenServicePoints(handler) {
82
+ ServiceChangeHandlers.delete(handler);
83
+ }
84
+ ComponentsRegistry.listen((component) => {
85
+ for (const service of ServicePoints.values()) {
86
+ if (service.descriptor.providers?.includes(component.id)) {
87
+ ServiceChangeHandlers.forEach(l => l(service));
88
+ }
89
+ }
90
+ });
91
+ async function fetchComponentsService(components_ids, service, servicepoint, log) {
92
+ const services = [];
93
+ if (Array.isArray(components_ids) && components_ids.length > 0) {
94
+ for (const component_id of components_ids) {
95
+ const component = acquireComponent(component_id);
96
+ if (await component.fetch()) {
97
+ const srv = await component.acquireResource(service).fetch();
98
+ if (srv) {
99
+ services.push(srv);
100
+ }
101
+ else {
102
+ log.notifyError(new Error(`ServicePoint '${servicepoint}': component '${component_id}' not implement service '${service}'`));
103
+ }
104
+ }
105
+ else {
106
+ log.notifyError(new Error(`ServicePoint '${servicepoint}': component '${component_id}' not found`));
107
+ }
108
+ }
109
+ }
110
+ return services;
111
+ }
112
+ export function acquireServicePointDescriptor(id) {
113
+ const settings = getSettings();
114
+ let desc = settings.get("service_points", id);
115
+ if (!desc)
116
+ desc = { id, providers: [], properties: {} };
117
+ return desc;
118
+ }
119
+ export function updateServicePointDescriptor(id, properties) {
120
+ const settings = getSettings();
121
+ let desc = settings.get("service_points", id);
122
+ if (desc) {
123
+ let hasChanged = false;
124
+ for (const key in properties) {
125
+ const value = properties[key];
126
+ if (value !== undefined && desc[key] != value) {
127
+ desc[key] = value;
128
+ hasChanged = true;
129
+ }
130
+ }
131
+ hasChanged && settings.set("service_points", id, desc);
132
+ }
133
+ else {
134
+ desc = { id, providers: [], properties };
135
+ settings.set("service_points", id, desc);
136
+ }
137
+ return desc;
138
+ }
139
+ listenSettings((group, id) => {
140
+ if (group === "service_points") {
141
+ const svc = ServicePoints.get(id);
142
+ if (svc) {
143
+ const desc = getSettings().get("service_points", id);
144
+ svc.reset(desc);
145
+ console.log("[Update Service Point]", id);
146
+ }
147
+ }
148
+ });
149
+ export function getServicePoint(id) {
150
+ return ServicePoints.get(id);
151
+ }
152
+ export function acquireServicePoint(id) {
153
+ let svc = ServicePoints.get(id);
154
+ if (!svc) {
155
+ svc = new ServicePoint(acquireServicePointDescriptor(id));
156
+ ServicePoints.set(svc.id, svc);
157
+ }
158
+ return svc;
159
+ }
160
+ export function createServicePoint(service, name, properties) {
161
+ const id = service.resource + "/" + name;
162
+ updateServicePointDescriptor(id, properties);
163
+ return acquireServicePoint(id);
164
+ }
@@ -0,0 +1,52 @@
1
+ import type { JSONSchema } from "../schema/schema.ts";
2
+ import type { ZodType } from "zod";
3
+ /**
4
+ * ServiceSpecification defines the metadata and schema for a service interface.
5
+ * It describes the contract that providers must implement and consumers can rely on.
6
+ *
7
+ * @template I - The TypeScript interface type this service represents
8
+ * @template P - The type of properties (hyperparameters) for service specialization
9
+ */
10
+ export interface ServiceSpecification<I = unknown, P = unknown> {
11
+ /** Unique identifier for the service specification (URI or qualified name) */
12
+ $spec: string;
13
+ /** Semantic version of the specification (e.g., "1.0.0") */
14
+ version: string;
15
+ /**
16
+ * JSON Schema defining the service interface including:
17
+ * - title, description (metadata)
18
+ * - properties (hyperparameters for service specialization)
19
+ * - All standard JSON Schema validation rules
20
+ */
21
+ schema?: JSONSchema;
22
+ /**
23
+ * Zod schema for runtime validation and compile-time type inference.
24
+ * Bridges runtime validation with TypeScript's static type system.
25
+ */
26
+ properties?: ZodType<P>;
27
+ /** Category or domain the service belongs to */
28
+ category?: string;
29
+ /** Tags for discovery and filtering */
30
+ tags?: string[];
31
+ /** Minimum compatible version for consumers */
32
+ minCompatibleVersion?: string;
33
+ }
34
+ /**
35
+ * Result of checking compatibility between consumer and provider
36
+ */
37
+ export interface ServiceCompatibility {
38
+ /** Whether the service is compatible */
39
+ compatible: boolean;
40
+ /** Reason for incompatibility if not compatible */
41
+ reason?: string;
42
+ /** Warnings about potential issues */
43
+ warnings?: string[];
44
+ }
45
+ /**
46
+ * Check if a provider version is compatible with a consumer's required version
47
+ */
48
+ export declare function checkVersionCompatibility(requiredVersion: string, providedVersion: string, minCompatibleVersion?: string): ServiceCompatibility;
49
+ /**
50
+ * Create a service specification with full metadata
51
+ */
52
+ export declare function defineServiceSpec<I = unknown, P = unknown>(spec: ServiceSpecification<I, P>): ServiceSpecification<I, P>;
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Check if a provider version is compatible with a consumer's required version
3
+ */
4
+ export function checkVersionCompatibility(requiredVersion, providedVersion, minCompatibleVersion) {
5
+ const required = parseVersion(requiredVersion);
6
+ const provided = parseVersion(providedVersion);
7
+ // Exact match is always compatible
8
+ if (requiredVersion === providedVersion) {
9
+ return { compatible: true };
10
+ }
11
+ // Major version must match for compatibility
12
+ if (required.major !== provided.major) {
13
+ return {
14
+ compatible: false,
15
+ reason: `Major version mismatch: required ${required.major}.x, provided ${provided.major}.x`
16
+ };
17
+ }
18
+ // Provider version must be >= required version
19
+ if (provided.minor < required.minor) {
20
+ return {
21
+ compatible: false,
22
+ reason: `Provider version ${providedVersion} is older than required ${requiredVersion}`
23
+ };
24
+ }
25
+ // Check minimum compatible version if specified
26
+ if (minCompatibleVersion) {
27
+ const minCompat = parseVersion(minCompatibleVersion);
28
+ if (required.major < minCompat.major ||
29
+ (required.major === minCompat.major && required.minor < minCompat.minor)) {
30
+ return {
31
+ compatible: false,
32
+ reason: `Required version ${requiredVersion} is below minimum compatible version ${minCompatibleVersion}`
33
+ };
34
+ }
35
+ }
36
+ return {
37
+ compatible: true,
38
+ warnings: provided.minor > required.minor
39
+ ? [`Provider version ${providedVersion} is newer than required ${requiredVersion}`]
40
+ : undefined
41
+ };
42
+ }
43
+ function parseVersion(version) {
44
+ const parts = version.split(".").map(Number);
45
+ return {
46
+ major: parts[0] || 0,
47
+ minor: parts[1] || 0,
48
+ patch: parts[2] || 0
49
+ };
50
+ }
51
+ // =============================================================================
52
+ // Service Specification Factory
53
+ // =============================================================================
54
+ /**
55
+ * Create a service specification with full metadata
56
+ */
57
+ export function defineServiceSpec(spec) {
58
+ return spec;
59
+ }
@@ -0,0 +1,29 @@
1
+ export type CommonSetting = Record<string, any>;
2
+ export type SettingGroup = "service_points" | "components" | "shareds";
3
+ export type SettingStores<T> = {
4
+ [id in SettingGroup]: Record<string, T>;
5
+ };
6
+ export declare enum WriteMode {
7
+ Default = 0,
8
+ Reset = 1,
9
+ Temporary = 2
10
+ }
11
+ export declare class AccountSettings {
12
+ readonly name: string;
13
+ key: string;
14
+ stores: SettingStores<string>;
15
+ temporaries: SettingStores<string>;
16
+ settings: SettingStores<CommonSetting>;
17
+ constructor(name: string);
18
+ get<T = any>(group: SettingGroup, key: string): T;
19
+ set<T = any>(group: SettingGroup, key: string, descriptor: T, mode?: WriteMode): boolean;
20
+ list(group: SettingGroup): string[];
21
+ read(key: string): string;
22
+ write(group: SettingGroup, key: string, data: string, mode: WriteMode): boolean;
23
+ restore(stores: SettingStores<string>): void;
24
+ }
25
+ type SettingsChangeHandler = (group: SettingGroup, id: string) => void;
26
+ export declare function getSettings(): AccountSettings;
27
+ export declare function listenSettings(handler: SettingsChangeHandler): SettingsChangeHandler;
28
+ export declare function unlistenSettings(handler: SettingsChangeHandler): void;
29
+ export {};