@milaboratories/pl-model-common 1.29.0 → 1.31.0

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 (105) hide show
  1. package/dist/bmodel/block_config.d.ts +1 -0
  2. package/dist/bmodel/code.d.ts +1 -0
  3. package/dist/driver_kit.d.ts +1 -1
  4. package/dist/drivers/index.d.ts +7 -7
  5. package/dist/drivers/index.js +2 -2
  6. package/dist/drivers/pframe/data_types.cjs +0 -15
  7. package/dist/drivers/pframe/data_types.cjs.map +1 -1
  8. package/dist/drivers/pframe/data_types.d.ts +14 -60
  9. package/dist/drivers/pframe/data_types.js +1 -13
  10. package/dist/drivers/pframe/data_types.js.map +1 -1
  11. package/dist/drivers/pframe/driver.cjs.map +1 -1
  12. package/dist/drivers/pframe/driver.d.ts +13 -5
  13. package/dist/drivers/pframe/driver.js.map +1 -1
  14. package/dist/drivers/pframe/index.d.ts +6 -6
  15. package/dist/drivers/pframe/index.js +2 -2
  16. package/dist/drivers/pframe/pframe.d.ts +2 -2
  17. package/dist/drivers/pframe/query/query_common.d.ts +2 -2
  18. package/dist/drivers/pframe/query/query_data.d.ts +1 -1
  19. package/dist/drivers/pframe/query/query_spec.d.ts +2 -2
  20. package/dist/drivers/pframe/spec/ids.d.ts +2 -2
  21. package/dist/drivers/pframe/spec/index.d.ts +1 -1
  22. package/dist/drivers/pframe/spec/index.js +1 -1
  23. package/dist/drivers/pframe/spec/selectors.d.ts +1 -1
  24. package/dist/drivers/pframe/spec/spec.cjs +14 -1
  25. package/dist/drivers/pframe/spec/spec.cjs.map +1 -1
  26. package/dist/drivers/pframe/spec/spec.d.ts +7 -1
  27. package/dist/drivers/pframe/spec/spec.js +14 -2
  28. package/dist/drivers/pframe/spec/spec.js.map +1 -1
  29. package/dist/drivers/pframe/spec_driver.d.ts +36 -6
  30. package/dist/drivers/pframe/table_calculate.cjs.map +1 -1
  31. package/dist/drivers/pframe/table_calculate.d.ts +5 -6
  32. package/dist/drivers/pframe/table_calculate.js.map +1 -1
  33. package/dist/drivers/pframe/table_common.d.ts +1 -1
  34. package/dist/drivers/pframe/unique_values.d.ts +2 -2
  35. package/dist/errors.cjs +48 -0
  36. package/dist/errors.cjs.map +1 -1
  37. package/dist/errors.d.ts +25 -1
  38. package/dist/errors.js +37 -1
  39. package/dist/errors.js.map +1 -1
  40. package/dist/flags/block_flags.cjs.map +1 -1
  41. package/dist/flags/block_flags.d.ts +4 -1
  42. package/dist/flags/block_flags.js.map +1 -1
  43. package/dist/flags/flag_utils.d.ts +1 -1
  44. package/dist/flags/index.d.ts +3 -0
  45. package/dist/index.cjs +38 -3
  46. package/dist/index.d.ts +31 -22
  47. package/dist/index.js +12 -4
  48. package/dist/pool/query.d.ts +1 -1
  49. package/dist/pool_entry.cjs +30 -0
  50. package/dist/pool_entry.cjs.map +1 -0
  51. package/dist/pool_entry.d.ts +30 -0
  52. package/dist/pool_entry.js +29 -0
  53. package/dist/pool_entry.js.map +1 -0
  54. package/dist/services/index.cjs +6 -0
  55. package/dist/services/index.d.ts +6 -0
  56. package/dist/services/index.js +6 -0
  57. package/dist/services/service_capabilities.cjs +51 -0
  58. package/dist/services/service_capabilities.cjs.map +1 -0
  59. package/dist/services/service_capabilities.d.ts +33 -0
  60. package/dist/services/service_capabilities.js +46 -0
  61. package/dist/services/service_capabilities.js.map +1 -0
  62. package/dist/services/service_declarations.cjs +17 -0
  63. package/dist/services/service_declarations.cjs.map +1 -0
  64. package/dist/services/service_declarations.d.ts +16 -0
  65. package/dist/services/service_declarations.js +17 -0
  66. package/dist/services/service_declarations.js.map +1 -0
  67. package/dist/services/service_injector_factory.cjs +19 -0
  68. package/dist/services/service_injector_factory.cjs.map +1 -0
  69. package/dist/services/service_injector_factory.d.ts +8 -0
  70. package/dist/services/service_injector_factory.js +18 -0
  71. package/dist/services/service_injector_factory.js.map +1 -0
  72. package/dist/services/service_injectors.cjs +48 -0
  73. package/dist/services/service_injectors.cjs.map +1 -0
  74. package/dist/services/service_injectors.d.ts +23 -0
  75. package/dist/services/service_injectors.js +46 -0
  76. package/dist/services/service_injectors.js.map +1 -0
  77. package/dist/services/service_registry.cjs +52 -0
  78. package/dist/services/service_registry.cjs.map +1 -0
  79. package/dist/services/service_registry.d.ts +25 -0
  80. package/dist/services/service_registry.js +51 -0
  81. package/dist/services/service_registry.js.map +1 -0
  82. package/dist/services/service_types.cjs +30 -0
  83. package/dist/services/service_types.cjs.map +1 -0
  84. package/dist/services/service_types.d.ts +45 -0
  85. package/dist/services/service_types.js +28 -0
  86. package/dist/services/service_types.js.map +1 -0
  87. package/package.json +4 -4
  88. package/src/drivers/pframe/data_types.ts +18 -140
  89. package/src/drivers/pframe/driver.ts +11 -1
  90. package/src/drivers/pframe/spec/spec.ts +16 -2
  91. package/src/drivers/pframe/spec_driver.ts +37 -5
  92. package/src/drivers/pframe/table_calculate.ts +3 -4
  93. package/src/errors.ts +53 -0
  94. package/src/flags/block_flags.ts +5 -2
  95. package/src/index.ts +2 -0
  96. package/src/pool_entry.ts +42 -0
  97. package/src/services/index.ts +5 -0
  98. package/src/services/service_capabilities.test.ts +119 -0
  99. package/src/services/service_capabilities.ts +64 -0
  100. package/src/services/service_declarations.ts +25 -0
  101. package/src/services/service_injector_factory.ts +27 -0
  102. package/src/services/service_injectors.ts +79 -0
  103. package/src/services/service_registry.test.ts +69 -0
  104. package/src/services/service_registry.ts +94 -0
  105. package/src/services/service_types.ts +114 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service_declarations.cjs","names":["service"],"sources":["../../src/services/service_declarations.ts"],"sourcesContent":["/**\n * Service declarations — add new services here.\n *\n * After adding a service, fix type errors in these files:\n *\n * Model side:\n * - lib/node/pl-middle-layer/src/js_render/service_injectors.ts — VM bridge for workflow scripts\n * - lib/node/pl-middle-layer/src/middle_layer/middle_layer.ts — ModelServiceRegistry factory\n *\n * UI side:\n * - lib/model/common/src/services/service_injector_factory.ts — driver method wrappers (node services only)\n * - sdk/ui-vue/src/internal/createAppV3.ts — UiServiceRegistry factory\n *\n * Optional:\n * - sdk/model/src/services/block_service_flags.ts — only if default-required by all blocks\n */\n\nimport type { PFrameDriver, PFrameModelDriver } from \"../drivers/pframe/driver\";\nimport type { PFrameSpecDriver } from \"../drivers/pframe/spec_driver\";\nimport { service } from \"./service_types\";\n\nexport const Services = {\n PFrameSpec: service<PFrameSpecDriver, PFrameSpecDriver>()({ type: \"wasm\", name: \"pframeSpec\" }),\n PFrame: service<PFrameModelDriver, PFrameDriver>()({ type: \"node\", name: \"pframe\" }),\n};\n"],"mappings":";;;AAqBA,MAAa,WAAW;CACtB,YAAYA,+BAA6C,CAAC;EAAE,MAAM;EAAQ,MAAM;EAAc,CAAC;CAC/F,QAAQA,+BAA0C,CAAC;EAAE,MAAM;EAAQ,MAAM;EAAU,CAAC;CACrF"}
@@ -0,0 +1,16 @@
1
+ import { Branded } from "../branding.js";
2
+ import { PColumn } from "../drivers/pframe/spec/spec.js";
3
+ import { DataInfo, PColumnValues } from "../drivers/pframe/data_info.js";
4
+ import { PFrameSpecDriver } from "../drivers/pframe/spec_driver.js";
5
+ import { PFrameDriver, PFrameModelDriver } from "../drivers/pframe/driver.js";
6
+ import { ServiceTypesLike } from "./service_types.js";
7
+ import "../index.js";
8
+
9
+ //#region src/services/service_declarations.d.ts
10
+ declare const Services: {
11
+ PFrameSpec: Branded<"pframeSpec", ServiceTypesLike<PFrameSpecDriver, PFrameSpecDriver, "wasm">>;
12
+ PFrame: Branded<"pframe", ServiceTypesLike<PFrameModelDriver<PColumn<string | PColumnValues | DataInfo<string>>>, PFrameDriver, "node">>;
13
+ };
14
+ //#endregion
15
+ export { Services };
16
+ //# sourceMappingURL=service_declarations.d.ts.map
@@ -0,0 +1,17 @@
1
+ import { service } from "./service_types.js";
2
+
3
+ //#region src/services/service_declarations.ts
4
+ const Services = {
5
+ PFrameSpec: service()({
6
+ type: "wasm",
7
+ name: "pframeSpec"
8
+ }),
9
+ PFrame: service()({
10
+ type: "node",
11
+ name: "pframe"
12
+ })
13
+ };
14
+
15
+ //#endregion
16
+ export { Services };
17
+ //# sourceMappingURL=service_declarations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service_declarations.js","names":[],"sources":["../../src/services/service_declarations.ts"],"sourcesContent":["/**\n * Service declarations — add new services here.\n *\n * After adding a service, fix type errors in these files:\n *\n * Model side:\n * - lib/node/pl-middle-layer/src/js_render/service_injectors.ts — VM bridge for workflow scripts\n * - lib/node/pl-middle-layer/src/middle_layer/middle_layer.ts — ModelServiceRegistry factory\n *\n * UI side:\n * - lib/model/common/src/services/service_injector_factory.ts — driver method wrappers (node services only)\n * - sdk/ui-vue/src/internal/createAppV3.ts — UiServiceRegistry factory\n *\n * Optional:\n * - sdk/model/src/services/block_service_flags.ts — only if default-required by all blocks\n */\n\nimport type { PFrameDriver, PFrameModelDriver } from \"../drivers/pframe/driver\";\nimport type { PFrameSpecDriver } from \"../drivers/pframe/spec_driver\";\nimport { service } from \"./service_types\";\n\nexport const Services = {\n PFrameSpec: service<PFrameSpecDriver, PFrameSpecDriver>()({ type: \"wasm\", name: \"pframeSpec\" }),\n PFrame: service<PFrameModelDriver, PFrameDriver>()({ type: \"node\", name: \"pframe\" }),\n};\n"],"mappings":";;;AAqBA,MAAa,WAAW;CACtB,YAAY,SAA6C,CAAC;EAAE,MAAM;EAAQ,MAAM;EAAc,CAAC;CAC/F,QAAQ,SAA0C,CAAC;EAAE,MAAM;EAAQ,MAAM;EAAU,CAAC;CACrF"}
@@ -0,0 +1,19 @@
1
+
2
+ //#region src/services/service_injector_factory.ts
3
+ function createUiServiceInjectors(driverKit) {
4
+ const { pFrameDriver } = driverKit;
5
+ return { PFrame: {
6
+ findColumns: (handle, request) => pFrameDriver.findColumns(handle, request),
7
+ getColumnSpec: (handle, columnId) => pFrameDriver.getColumnSpec(handle, columnId),
8
+ listColumns: (handle) => pFrameDriver.listColumns(handle),
9
+ calculateTableData: (handle, request, range) => pFrameDriver.calculateTableData(handle, request, range),
10
+ getUniqueValues: (handle, request) => pFrameDriver.getUniqueValues(handle, request),
11
+ getShape: (handle) => pFrameDriver.getShape(handle),
12
+ getSpec: (handle) => pFrameDriver.getSpec(handle),
13
+ getData: (handle, columnIndices, range) => pFrameDriver.getData(handle, columnIndices, range)
14
+ } };
15
+ }
16
+
17
+ //#endregion
18
+ exports.createUiServiceInjectors = createUiServiceInjectors;
19
+ //# sourceMappingURL=service_injector_factory.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service_injector_factory.cjs","names":[],"sources":["../../src/services/service_injector_factory.ts"],"sourcesContent":["/**\n * UI service injector factory.\n *\n * When adding a new node service, add its method wrappers here.\n * Everything else (SERVICE_METHOD_MAP, buildServiceInfo, UiServiceInjectorMap)\n * auto-derives from this factory + Services in service_declarations.ts.\n */\n\nimport type { DriverKit } from \"../driver_kit\";\nimport type { UiServiceInjectorMap } from \"./service_injectors\";\n\nexport function createUiServiceInjectors(driverKit: DriverKit): UiServiceInjectorMap {\n const { pFrameDriver } = driverKit;\n return {\n PFrame: {\n findColumns: (handle, request) => pFrameDriver.findColumns(handle, request),\n getColumnSpec: (handle, columnId) => pFrameDriver.getColumnSpec(handle, columnId),\n listColumns: (handle) => pFrameDriver.listColumns(handle),\n calculateTableData: (handle, request, range) =>\n pFrameDriver.calculateTableData(handle, request, range),\n getUniqueValues: (handle, request) => pFrameDriver.getUniqueValues(handle, request),\n getShape: (handle) => pFrameDriver.getShape(handle),\n getSpec: (handle) => pFrameDriver.getSpec(handle),\n getData: (handle, columnIndices, range) => pFrameDriver.getData(handle, columnIndices, range),\n },\n };\n}\n"],"mappings":";;AAWA,SAAgB,yBAAyB,WAA4C;CACnF,MAAM,EAAE,iBAAiB;AACzB,QAAO,EACL,QAAQ;EACN,cAAc,QAAQ,YAAY,aAAa,YAAY,QAAQ,QAAQ;EAC3E,gBAAgB,QAAQ,aAAa,aAAa,cAAc,QAAQ,SAAS;EACjF,cAAc,WAAW,aAAa,YAAY,OAAO;EACzD,qBAAqB,QAAQ,SAAS,UACpC,aAAa,mBAAmB,QAAQ,SAAS,MAAM;EACzD,kBAAkB,QAAQ,YAAY,aAAa,gBAAgB,QAAQ,QAAQ;EACnF,WAAW,WAAW,aAAa,SAAS,OAAO;EACnD,UAAU,WAAW,aAAa,QAAQ,OAAO;EACjD,UAAU,QAAQ,eAAe,UAAU,aAAa,QAAQ,QAAQ,eAAe,MAAM;EAC9F,EACF"}
@@ -0,0 +1,8 @@
1
+ import { DriverKit } from "../driver_kit.js";
2
+ import { UiServiceInjectorMap } from "./service_injectors.js";
3
+
4
+ //#region src/services/service_injector_factory.d.ts
5
+ declare function createUiServiceInjectors(driverKit: DriverKit): UiServiceInjectorMap;
6
+ //#endregion
7
+ export { createUiServiceInjectors };
8
+ //# sourceMappingURL=service_injector_factory.d.ts.map
@@ -0,0 +1,18 @@
1
+ //#region src/services/service_injector_factory.ts
2
+ function createUiServiceInjectors(driverKit) {
3
+ const { pFrameDriver } = driverKit;
4
+ return { PFrame: {
5
+ findColumns: (handle, request) => pFrameDriver.findColumns(handle, request),
6
+ getColumnSpec: (handle, columnId) => pFrameDriver.getColumnSpec(handle, columnId),
7
+ listColumns: (handle) => pFrameDriver.listColumns(handle),
8
+ calculateTableData: (handle, request, range) => pFrameDriver.calculateTableData(handle, request, range),
9
+ getUniqueValues: (handle, request) => pFrameDriver.getUniqueValues(handle, request),
10
+ getShape: (handle) => pFrameDriver.getShape(handle),
11
+ getSpec: (handle) => pFrameDriver.getSpec(handle),
12
+ getData: (handle, columnIndices, range) => pFrameDriver.getData(handle, columnIndices, range)
13
+ } };
14
+ }
15
+
16
+ //#endregion
17
+ export { createUiServiceInjectors };
18
+ //# sourceMappingURL=service_injector_factory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service_injector_factory.js","names":[],"sources":["../../src/services/service_injector_factory.ts"],"sourcesContent":["/**\n * UI service injector factory.\n *\n * When adding a new node service, add its method wrappers here.\n * Everything else (SERVICE_METHOD_MAP, buildServiceInfo, UiServiceInjectorMap)\n * auto-derives from this factory + Services in service_declarations.ts.\n */\n\nimport type { DriverKit } from \"../driver_kit\";\nimport type { UiServiceInjectorMap } from \"./service_injectors\";\n\nexport function createUiServiceInjectors(driverKit: DriverKit): UiServiceInjectorMap {\n const { pFrameDriver } = driverKit;\n return {\n PFrame: {\n findColumns: (handle, request) => pFrameDriver.findColumns(handle, request),\n getColumnSpec: (handle, columnId) => pFrameDriver.getColumnSpec(handle, columnId),\n listColumns: (handle) => pFrameDriver.listColumns(handle),\n calculateTableData: (handle, request, range) =>\n pFrameDriver.calculateTableData(handle, request, range),\n getUniqueValues: (handle, request) => pFrameDriver.getUniqueValues(handle, request),\n getShape: (handle) => pFrameDriver.getShape(handle),\n getSpec: (handle) => pFrameDriver.getSpec(handle),\n getData: (handle, columnIndices, range) => pFrameDriver.getData(handle, columnIndices, range),\n },\n };\n}\n"],"mappings":";AAWA,SAAgB,yBAAyB,WAA4C;CACnF,MAAM,EAAE,iBAAiB;AACzB,QAAO,EACL,QAAQ;EACN,cAAc,QAAQ,YAAY,aAAa,YAAY,QAAQ,QAAQ;EAC3E,gBAAgB,QAAQ,aAAa,aAAa,cAAc,QAAQ,SAAS;EACjF,cAAc,WAAW,aAAa,YAAY,OAAO;EACzD,qBAAqB,QAAQ,SAAS,UACpC,aAAa,mBAAmB,QAAQ,SAAS,MAAM;EACzD,kBAAkB,QAAQ,YAAY,aAAa,gBAAgB,QAAQ,QAAQ;EACnF,WAAW,WAAW,aAAa,SAAS,OAAO;EACnD,UAAU,WAAW,aAAa,QAAQ,OAAO;EACjD,UAAU,QAAQ,eAAe,UAAU,aAAa,QAAQ,QAAQ,eAAe,MAAM;EAC9F,EACF"}
@@ -0,0 +1,48 @@
1
+ const require_service_declarations = require('./service_declarations.cjs');
2
+ const require_service_capabilities = require('./service_capabilities.cjs');
3
+ const require_service_injector_factory = require('./service_injector_factory.cjs');
4
+
5
+ //#region src/services/service_injectors.ts
6
+ let cachedKit;
7
+ let cachedInjectors;
8
+ function getOrCreateInjectors(driverKit) {
9
+ if (!cachedInjectors || cachedKit !== driverKit) {
10
+ cachedKit = driverKit;
11
+ cachedInjectors = require_service_injector_factory.createUiServiceInjectors(driverKit);
12
+ }
13
+ return cachedInjectors;
14
+ }
15
+ /** Resolve the injector for a given service ID. Caches injectors per DriverKit reference. */
16
+ function resolveUiInjector(driverKit, serviceId) {
17
+ const injectors = getOrCreateInjectors(driverKit);
18
+ const key = Object.keys(require_service_declarations.Services).find((k) => require_service_declarations.Services[k] === serviceId);
19
+ if (!key) return null;
20
+ return injectors[key];
21
+ }
22
+ /**
23
+ * Static map of ServiceName → method names, auto-derived from the injector shape.
24
+ * Computed once at module load. The stub DriverKit is never called — it only
25
+ * provides a target so the closures in createUiServiceInjectors have own-property
26
+ * keys that getMethodNames can introspect.
27
+ */
28
+ const SERVICE_METHOD_MAP = (() => {
29
+ const injectors = require_service_injector_factory.createUiServiceInjectors(new Proxy({}, { get: () => new Proxy({}, { get: () => () => {} }) }));
30
+ const result = {};
31
+ for (const key of Object.keys(require_service_declarations.Services)) {
32
+ const serviceId = require_service_declarations.Services[key];
33
+ const injector = injectors[key];
34
+ result[serviceId] = injector ? require_service_capabilities.getMethodNames(injector) : [];
35
+ }
36
+ return result;
37
+ })();
38
+ /** Build service info for a block from its feature flags. */
39
+ function buildServiceInfo(featureFlags) {
40
+ const serviceIds = require_service_capabilities.resolveRequiredServices(featureFlags);
41
+ return Object.fromEntries(serviceIds.map((id) => [id, SERVICE_METHOD_MAP[id] ?? []]));
42
+ }
43
+
44
+ //#endregion
45
+ exports.SERVICE_METHOD_MAP = SERVICE_METHOD_MAP;
46
+ exports.buildServiceInfo = buildServiceInfo;
47
+ exports.resolveUiInjector = resolveUiInjector;
48
+ //# sourceMappingURL=service_injectors.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service_injectors.cjs","names":["createUiServiceInjectors","Services","getMethodNames","resolveRequiredServices"],"sources":["../../src/services/service_injectors.ts"],"sourcesContent":["/**\n * UI service injectors — auto-derived types, method map, and service info builder.\n *\n * The factory (createUiServiceInjectors) lives in service_injector_factory.ts —\n * that's the only file to edit when adding a new node service.\n */\n\nimport type { InferServiceKind, InferServiceUi, ServiceBrand, ServiceName } from \"./service_types\";\nimport type { DriverKit } from \"../driver_kit\";\nimport { Services } from \"./service_declarations\";\nimport { getMethodNames, resolveRequiredServices } from \"./service_capabilities\";\nimport { createUiServiceInjectors } from \"./service_injector_factory\";\n\nexport { createUiServiceInjectors } from \"./service_injector_factory\";\n\ntype NodeServiceKeys = {\n [K in keyof typeof Services]: InferServiceKind<ServiceBrand<(typeof Services)[K]>> extends \"node\"\n ? K\n : never;\n}[keyof typeof Services];\n\n/** Auto-derived map of node service keys to their UI-side driver interfaces. */\nexport type UiServiceInjectorMap = {\n [K in NodeServiceKeys]: InferServiceUi<ServiceBrand<(typeof Services)[K]>>;\n};\n\nlet cachedKit: DriverKit | undefined;\nlet cachedInjectors: UiServiceInjectorMap | undefined;\n\nfunction getOrCreateInjectors(driverKit: DriverKit): UiServiceInjectorMap {\n if (!cachedInjectors || cachedKit !== driverKit) {\n cachedKit = driverKit;\n cachedInjectors = createUiServiceInjectors(driverKit);\n }\n return cachedInjectors;\n}\n\n/** Resolve the injector for a given service ID. Caches injectors per DriverKit reference. */\nexport function resolveUiInjector(\n driverKit: DriverKit,\n serviceId: ServiceName,\n): UiServiceInjectorMap[keyof UiServiceInjectorMap] | null {\n const injectors = getOrCreateInjectors(driverKit);\n const key = Object.keys(Services).find(\n (k) => Services[k as keyof typeof Services] === serviceId,\n ) as NodeServiceKeys | undefined;\n if (!key) return null;\n return injectors[key];\n}\n\n/**\n * Static map of ServiceName → method names, auto-derived from the injector shape.\n * Computed once at module load. The stub DriverKit is never called — it only\n * provides a target so the closures in createUiServiceInjectors have own-property\n * keys that getMethodNames can introspect.\n */\nexport const SERVICE_METHOD_MAP: Readonly<Record<string, string[]>> = (() => {\n const stubKit = new Proxy({} as DriverKit, {\n get: () => new Proxy({}, { get: () => () => {} }),\n });\n const injectors = createUiServiceInjectors(stubKit);\n const result: Record<string, string[]> = {};\n for (const key of Object.keys(Services) as (keyof typeof Services)[]) {\n const serviceId = Services[key];\n const injector = injectors[key as NodeServiceKeys];\n result[serviceId] = injector ? getMethodNames(injector) : [];\n }\n return result;\n})();\n\n/** Build service info for a block from its feature flags. */\nexport function buildServiceInfo(\n featureFlags: Record<string, unknown>,\n): Record<ServiceName, string[]> {\n const serviceIds = resolveRequiredServices(featureFlags);\n return Object.fromEntries(\n serviceIds.map((id) => [id, SERVICE_METHOD_MAP[id as string] ?? []]),\n ) as Record<ServiceName, string[]>;\n}\n"],"mappings":";;;;;AA0BA,IAAI;AACJ,IAAI;AAEJ,SAAS,qBAAqB,WAA4C;AACxE,KAAI,CAAC,mBAAmB,cAAc,WAAW;AAC/C,cAAY;AACZ,oBAAkBA,0DAAyB,UAAU;;AAEvD,QAAO;;;AAIT,SAAgB,kBACd,WACA,WACyD;CACzD,MAAM,YAAY,qBAAqB,UAAU;CACjD,MAAM,MAAM,OAAO,KAAKC,sCAAS,CAAC,MAC/B,MAAMA,sCAAS,OAAgC,UACjD;AACD,KAAI,CAAC,IAAK,QAAO;AACjB,QAAO,UAAU;;;;;;;;AASnB,MAAa,4BAAgE;CAI3E,MAAM,YAAYD,0DAHF,IAAI,MAAM,EAAE,EAAe,EACzC,WAAW,IAAI,MAAM,EAAE,EAAE,EAAE,iBAAiB,IAAI,CAAC,EAClD,CAAC,CACiD;CACnD,MAAM,SAAmC,EAAE;AAC3C,MAAK,MAAM,OAAO,OAAO,KAAKC,sCAAS,EAA+B;EACpE,MAAM,YAAYA,sCAAS;EAC3B,MAAM,WAAW,UAAU;AAC3B,SAAO,aAAa,WAAWC,4CAAe,SAAS,GAAG,EAAE;;AAE9D,QAAO;IACL;;AAGJ,SAAgB,iBACd,cAC+B;CAC/B,MAAM,aAAaC,qDAAwB,aAAa;AACxD,QAAO,OAAO,YACZ,WAAW,KAAK,OAAO,CAAC,IAAI,mBAAmB,OAAiB,EAAE,CAAC,CAAC,CACrE"}
@@ -0,0 +1,23 @@
1
+ import { Services } from "./service_declarations.js";
2
+ import { InferServiceKind, InferServiceUi, ServiceBrand, ServiceName } from "./service_types.js";
3
+ import { DriverKit } from "../driver_kit.js";
4
+ import { createUiServiceInjectors } from "./service_injector_factory.js";
5
+
6
+ //#region src/services/service_injectors.d.ts
7
+ type NodeServiceKeys = { [K in keyof typeof Services]: InferServiceKind<ServiceBrand<(typeof Services)[K]>> extends "node" ? K : never }[keyof typeof Services];
8
+ /** Auto-derived map of node service keys to their UI-side driver interfaces. */
9
+ type UiServiceInjectorMap = { [K in NodeServiceKeys]: InferServiceUi<ServiceBrand<(typeof Services)[K]>> };
10
+ /** Resolve the injector for a given service ID. Caches injectors per DriverKit reference. */
11
+ declare function resolveUiInjector(driverKit: DriverKit, serviceId: ServiceName): UiServiceInjectorMap[keyof UiServiceInjectorMap] | null;
12
+ /**
13
+ * Static map of ServiceName → method names, auto-derived from the injector shape.
14
+ * Computed once at module load. The stub DriverKit is never called — it only
15
+ * provides a target so the closures in createUiServiceInjectors have own-property
16
+ * keys that getMethodNames can introspect.
17
+ */
18
+ declare const SERVICE_METHOD_MAP: Readonly<Record<string, string[]>>;
19
+ /** Build service info for a block from its feature flags. */
20
+ declare function buildServiceInfo(featureFlags: Record<string, unknown>): Record<ServiceName, string[]>;
21
+ //#endregion
22
+ export { SERVICE_METHOD_MAP, UiServiceInjectorMap, buildServiceInfo, resolveUiInjector };
23
+ //# sourceMappingURL=service_injectors.d.ts.map
@@ -0,0 +1,46 @@
1
+ import { Services } from "./service_declarations.js";
2
+ import { getMethodNames, resolveRequiredServices } from "./service_capabilities.js";
3
+ import { createUiServiceInjectors } from "./service_injector_factory.js";
4
+
5
+ //#region src/services/service_injectors.ts
6
+ let cachedKit;
7
+ let cachedInjectors;
8
+ function getOrCreateInjectors(driverKit) {
9
+ if (!cachedInjectors || cachedKit !== driverKit) {
10
+ cachedKit = driverKit;
11
+ cachedInjectors = createUiServiceInjectors(driverKit);
12
+ }
13
+ return cachedInjectors;
14
+ }
15
+ /** Resolve the injector for a given service ID. Caches injectors per DriverKit reference. */
16
+ function resolveUiInjector(driverKit, serviceId) {
17
+ const injectors = getOrCreateInjectors(driverKit);
18
+ const key = Object.keys(Services).find((k) => Services[k] === serviceId);
19
+ if (!key) return null;
20
+ return injectors[key];
21
+ }
22
+ /**
23
+ * Static map of ServiceName → method names, auto-derived from the injector shape.
24
+ * Computed once at module load. The stub DriverKit is never called — it only
25
+ * provides a target so the closures in createUiServiceInjectors have own-property
26
+ * keys that getMethodNames can introspect.
27
+ */
28
+ const SERVICE_METHOD_MAP = (() => {
29
+ const injectors = createUiServiceInjectors(new Proxy({}, { get: () => new Proxy({}, { get: () => () => {} }) }));
30
+ const result = {};
31
+ for (const key of Object.keys(Services)) {
32
+ const serviceId = Services[key];
33
+ const injector = injectors[key];
34
+ result[serviceId] = injector ? getMethodNames(injector) : [];
35
+ }
36
+ return result;
37
+ })();
38
+ /** Build service info for a block from its feature flags. */
39
+ function buildServiceInfo(featureFlags) {
40
+ const serviceIds = resolveRequiredServices(featureFlags);
41
+ return Object.fromEntries(serviceIds.map((id) => [id, SERVICE_METHOD_MAP[id] ?? []]));
42
+ }
43
+
44
+ //#endregion
45
+ export { SERVICE_METHOD_MAP, buildServiceInfo, resolveUiInjector };
46
+ //# sourceMappingURL=service_injectors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service_injectors.js","names":[],"sources":["../../src/services/service_injectors.ts"],"sourcesContent":["/**\n * UI service injectors — auto-derived types, method map, and service info builder.\n *\n * The factory (createUiServiceInjectors) lives in service_injector_factory.ts —\n * that's the only file to edit when adding a new node service.\n */\n\nimport type { InferServiceKind, InferServiceUi, ServiceBrand, ServiceName } from \"./service_types\";\nimport type { DriverKit } from \"../driver_kit\";\nimport { Services } from \"./service_declarations\";\nimport { getMethodNames, resolveRequiredServices } from \"./service_capabilities\";\nimport { createUiServiceInjectors } from \"./service_injector_factory\";\n\nexport { createUiServiceInjectors } from \"./service_injector_factory\";\n\ntype NodeServiceKeys = {\n [K in keyof typeof Services]: InferServiceKind<ServiceBrand<(typeof Services)[K]>> extends \"node\"\n ? K\n : never;\n}[keyof typeof Services];\n\n/** Auto-derived map of node service keys to their UI-side driver interfaces. */\nexport type UiServiceInjectorMap = {\n [K in NodeServiceKeys]: InferServiceUi<ServiceBrand<(typeof Services)[K]>>;\n};\n\nlet cachedKit: DriverKit | undefined;\nlet cachedInjectors: UiServiceInjectorMap | undefined;\n\nfunction getOrCreateInjectors(driverKit: DriverKit): UiServiceInjectorMap {\n if (!cachedInjectors || cachedKit !== driverKit) {\n cachedKit = driverKit;\n cachedInjectors = createUiServiceInjectors(driverKit);\n }\n return cachedInjectors;\n}\n\n/** Resolve the injector for a given service ID. Caches injectors per DriverKit reference. */\nexport function resolveUiInjector(\n driverKit: DriverKit,\n serviceId: ServiceName,\n): UiServiceInjectorMap[keyof UiServiceInjectorMap] | null {\n const injectors = getOrCreateInjectors(driverKit);\n const key = Object.keys(Services).find(\n (k) => Services[k as keyof typeof Services] === serviceId,\n ) as NodeServiceKeys | undefined;\n if (!key) return null;\n return injectors[key];\n}\n\n/**\n * Static map of ServiceName → method names, auto-derived from the injector shape.\n * Computed once at module load. The stub DriverKit is never called — it only\n * provides a target so the closures in createUiServiceInjectors have own-property\n * keys that getMethodNames can introspect.\n */\nexport const SERVICE_METHOD_MAP: Readonly<Record<string, string[]>> = (() => {\n const stubKit = new Proxy({} as DriverKit, {\n get: () => new Proxy({}, { get: () => () => {} }),\n });\n const injectors = createUiServiceInjectors(stubKit);\n const result: Record<string, string[]> = {};\n for (const key of Object.keys(Services) as (keyof typeof Services)[]) {\n const serviceId = Services[key];\n const injector = injectors[key as NodeServiceKeys];\n result[serviceId] = injector ? getMethodNames(injector) : [];\n }\n return result;\n})();\n\n/** Build service info for a block from its feature flags. */\nexport function buildServiceInfo(\n featureFlags: Record<string, unknown>,\n): Record<ServiceName, string[]> {\n const serviceIds = resolveRequiredServices(featureFlags);\n return Object.fromEntries(\n serviceIds.map((id) => [id, SERVICE_METHOD_MAP[id as string] ?? []]),\n ) as Record<ServiceName, string[]>;\n}\n"],"mappings":";;;;;AA0BA,IAAI;AACJ,IAAI;AAEJ,SAAS,qBAAqB,WAA4C;AACxE,KAAI,CAAC,mBAAmB,cAAc,WAAW;AAC/C,cAAY;AACZ,oBAAkB,yBAAyB,UAAU;;AAEvD,QAAO;;;AAIT,SAAgB,kBACd,WACA,WACyD;CACzD,MAAM,YAAY,qBAAqB,UAAU;CACjD,MAAM,MAAM,OAAO,KAAK,SAAS,CAAC,MAC/B,MAAM,SAAS,OAAgC,UACjD;AACD,KAAI,CAAC,IAAK,QAAO;AACjB,QAAO,UAAU;;;;;;;;AASnB,MAAa,4BAAgE;CAI3E,MAAM,YAAY,yBAHF,IAAI,MAAM,EAAE,EAAe,EACzC,WAAW,IAAI,MAAM,EAAE,EAAE,EAAE,iBAAiB,IAAI,CAAC,EAClD,CAAC,CACiD;CACnD,MAAM,SAAmC,EAAE;AAC3C,MAAK,MAAM,OAAO,OAAO,KAAK,SAAS,EAA+B;EACpE,MAAM,YAAY,SAAS;EAC3B,MAAM,WAAW,UAAU;AAC3B,SAAO,aAAa,WAAW,eAAe,SAAS,GAAG,EAAE;;AAE9D,QAAO;IACL;;AAGJ,SAAgB,iBACd,cAC+B;CAC/B,MAAM,aAAa,wBAAwB,aAAa;AACxD,QAAO,OAAO,YACZ,WAAW,KAAK,OAAO,CAAC,IAAI,mBAAmB,OAAiB,EAAE,CAAC,CAAC,CACrE"}
@@ -0,0 +1,52 @@
1
+ const require_errors = require('../errors.cjs');
2
+
3
+ //#region src/services/service_registry.ts
4
+ var ServiceRegistryBase = class {
5
+ registryName;
6
+ knownServices = /* @__PURE__ */ new Set();
7
+ factories = /* @__PURE__ */ new Map();
8
+ instances = /* @__PURE__ */ new Map();
9
+ constructor(registryName, serviceMap, factories) {
10
+ this.registryName = registryName;
11
+ for (const [key, factory] of Object.entries(factories)) {
12
+ const serviceId = serviceMap[key];
13
+ this.knownServices.add(serviceId);
14
+ if (factory !== null) this.factories.set(serviceId, factory);
15
+ }
16
+ }
17
+ async dispose() {
18
+ for (const instance of this.instances.values()) if (Symbol.asyncDispose in instance) await instance[Symbol.asyncDispose]();
19
+ else if (Symbol.dispose in instance) instance[Symbol.dispose]();
20
+ this.instances.clear();
21
+ }
22
+ getById(serviceId) {
23
+ if (!this.knownServices.has(serviceId)) throw new require_errors.ServiceNotRegisteredError(`Service "${serviceId}" is not registered in ${this.registryName}. Add it to the factory map.`);
24
+ if (this.instances.has(serviceId)) return this.instances.get(serviceId);
25
+ const factory = this.factories.get(serviceId);
26
+ if (!factory) return null;
27
+ const instance = factory();
28
+ this.instances.set(serviceId, instance);
29
+ return instance;
30
+ }
31
+ };
32
+ var ModelServiceRegistry = class extends ServiceRegistryBase {
33
+ constructor(serviceMap, factories) {
34
+ super("ModelServiceRegistry", serviceMap, factories);
35
+ }
36
+ get(id) {
37
+ return this.getById(id);
38
+ }
39
+ };
40
+ var UiServiceRegistry = class extends ServiceRegistryBase {
41
+ constructor(serviceMap, factories) {
42
+ super("UiServiceRegistry", serviceMap, factories);
43
+ }
44
+ get(id) {
45
+ return this.getById(id);
46
+ }
47
+ };
48
+
49
+ //#endregion
50
+ exports.ModelServiceRegistry = ModelServiceRegistry;
51
+ exports.UiServiceRegistry = UiServiceRegistry;
52
+ //# sourceMappingURL=service_registry.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service_registry.cjs","names":["ServiceNotRegisteredError"],"sources":["../../src/services/service_registry.ts"],"sourcesContent":["import type {\n ServiceTypesLike,\n InferServiceModel,\n InferServiceUi,\n ServiceName,\n ModelServiceFactoryMap,\n UiServiceFactoryMap,\n} from \"./service_types\";\nimport { ServiceNotRegisteredError } from \"../errors\";\nimport type { Services } from \"./service_declarations\";\n\ntype RegistryName = \"ModelServiceRegistry\" | \"UiServiceRegistry\";\ntype ServiceFactory = () => Record<string, Function>;\n\nclass ServiceRegistryBase {\n private readonly registryName: RegistryName;\n private readonly knownServices = new Set<ServiceName>();\n private readonly factories = new Map<ServiceName, ServiceFactory>();\n private readonly instances = new Map<ServiceName, Record<string, Function>>();\n\n protected constructor(\n registryName: RegistryName,\n serviceMap: Record<string, ServiceName>,\n factories: Record<string, (() => unknown) | null>,\n ) {\n this.registryName = registryName;\n for (const [key, factory] of Object.entries(factories)) {\n const serviceId = serviceMap[key];\n this.knownServices.add(serviceId);\n if (factory !== null) {\n this.factories.set(serviceId, factory as ServiceFactory);\n }\n }\n }\n\n async dispose(): Promise<void> {\n for (const instance of this.instances.values()) {\n if (Symbol.asyncDispose in instance) {\n await (instance as AsyncDisposable)[Symbol.asyncDispose]();\n } else if (Symbol.dispose in instance) {\n (instance as Disposable)[Symbol.dispose]();\n }\n }\n this.instances.clear();\n }\n\n protected getById(serviceId: ServiceName): Record<string, Function> | null {\n if (!this.knownServices.has(serviceId)) {\n throw new ServiceNotRegisteredError(\n `Service \"${serviceId}\" is not registered in ${this.registryName}. Add it to the factory map.`,\n );\n }\n if (this.instances.has(serviceId)) return this.instances.get(serviceId)!;\n\n const factory = this.factories.get(serviceId);\n if (!factory) return null;\n\n const instance = factory();\n this.instances.set(serviceId, instance);\n return instance;\n }\n}\n\nexport class ModelServiceRegistry<\n SMap extends Record<string, ServiceName> = typeof Services,\n> extends ServiceRegistryBase {\n constructor(serviceMap: SMap, factories: ModelServiceFactoryMap<SMap>) {\n super(\"ModelServiceRegistry\", serviceMap, factories);\n }\n\n get<S extends ServiceTypesLike>(\n id: ServiceName<S>,\n ):\n | ([unknown] extends [InferServiceModel<S>] ? Record<string, Function> : InferServiceModel<S>)\n | null;\n get(id: ServiceName): Record<string, Function> | null {\n return this.getById(id);\n }\n}\n\nexport class UiServiceRegistry<\n SMap extends Record<string, ServiceName> = typeof Services,\n> extends ServiceRegistryBase {\n constructor(serviceMap: SMap, factories: UiServiceFactoryMap<SMap>) {\n super(\"UiServiceRegistry\", serviceMap, factories);\n }\n\n get<S extends ServiceTypesLike>(\n id: ServiceName<S>,\n ): ([unknown] extends [InferServiceUi<S>] ? Record<string, Function> : InferServiceUi<S>) | null;\n get(id: ServiceName): Record<string, Function> | null {\n return this.getById(id);\n }\n}\n"],"mappings":";;;AAcA,IAAM,sBAAN,MAA0B;CACxB,AAAiB;CACjB,AAAiB,gCAAgB,IAAI,KAAkB;CACvD,AAAiB,4BAAY,IAAI,KAAkC;CACnE,AAAiB,4BAAY,IAAI,KAA4C;CAE7E,AAAU,YACR,cACA,YACA,WACA;AACA,OAAK,eAAe;AACpB,OAAK,MAAM,CAAC,KAAK,YAAY,OAAO,QAAQ,UAAU,EAAE;GACtD,MAAM,YAAY,WAAW;AAC7B,QAAK,cAAc,IAAI,UAAU;AACjC,OAAI,YAAY,KACd,MAAK,UAAU,IAAI,WAAW,QAA0B;;;CAK9D,MAAM,UAAyB;AAC7B,OAAK,MAAM,YAAY,KAAK,UAAU,QAAQ,CAC5C,KAAI,OAAO,gBAAgB,SACzB,OAAO,SAA6B,OAAO,eAAe;WACjD,OAAO,WAAW,SAC3B,CAAC,SAAwB,OAAO,UAAU;AAG9C,OAAK,UAAU,OAAO;;CAGxB,AAAU,QAAQ,WAAyD;AACzE,MAAI,CAAC,KAAK,cAAc,IAAI,UAAU,CACpC,OAAM,IAAIA,yCACR,YAAY,UAAU,yBAAyB,KAAK,aAAa,8BAClE;AAEH,MAAI,KAAK,UAAU,IAAI,UAAU,CAAE,QAAO,KAAK,UAAU,IAAI,UAAU;EAEvE,MAAM,UAAU,KAAK,UAAU,IAAI,UAAU;AAC7C,MAAI,CAAC,QAAS,QAAO;EAErB,MAAM,WAAW,SAAS;AAC1B,OAAK,UAAU,IAAI,WAAW,SAAS;AACvC,SAAO;;;AAIX,IAAa,uBAAb,cAEU,oBAAoB;CAC5B,YAAY,YAAkB,WAAyC;AACrE,QAAM,wBAAwB,YAAY,UAAU;;CAQtD,IAAI,IAAkD;AACpD,SAAO,KAAK,QAAQ,GAAG;;;AAI3B,IAAa,oBAAb,cAEU,oBAAoB;CAC5B,YAAY,YAAkB,WAAsC;AAClE,QAAM,qBAAqB,YAAY,UAAU;;CAMnD,IAAI,IAAkD;AACpD,SAAO,KAAK,QAAQ,GAAG"}
@@ -0,0 +1,25 @@
1
+ import { Services } from "./service_declarations.js";
2
+ import { InferServiceModel, InferServiceUi, ModelServiceFactoryMap, ServiceName, ServiceTypesLike, UiServiceFactoryMap } from "./service_types.js";
3
+
4
+ //#region src/services/service_registry.d.ts
5
+ type RegistryName = "ModelServiceRegistry" | "UiServiceRegistry";
6
+ declare class ServiceRegistryBase {
7
+ private readonly registryName;
8
+ private readonly knownServices;
9
+ private readonly factories;
10
+ private readonly instances;
11
+ protected constructor(registryName: RegistryName, serviceMap: Record<string, ServiceName>, factories: Record<string, (() => unknown) | null>);
12
+ dispose(): Promise<void>;
13
+ protected getById(serviceId: ServiceName): Record<string, Function> | null;
14
+ }
15
+ declare class ModelServiceRegistry<SMap extends Record<string, ServiceName> = typeof Services> extends ServiceRegistryBase {
16
+ constructor(serviceMap: SMap, factories: ModelServiceFactoryMap<SMap>);
17
+ get<S extends ServiceTypesLike>(id: ServiceName<S>): ([unknown] extends [InferServiceModel<S>] ? Record<string, Function> : InferServiceModel<S>) | null;
18
+ }
19
+ declare class UiServiceRegistry<SMap extends Record<string, ServiceName> = typeof Services> extends ServiceRegistryBase {
20
+ constructor(serviceMap: SMap, factories: UiServiceFactoryMap<SMap>);
21
+ get<S extends ServiceTypesLike>(id: ServiceName<S>): ([unknown] extends [InferServiceUi<S>] ? Record<string, Function> : InferServiceUi<S>) | null;
22
+ }
23
+ //#endregion
24
+ export { ModelServiceRegistry, UiServiceRegistry };
25
+ //# sourceMappingURL=service_registry.d.ts.map
@@ -0,0 +1,51 @@
1
+ import { ServiceNotRegisteredError } from "../errors.js";
2
+
3
+ //#region src/services/service_registry.ts
4
+ var ServiceRegistryBase = class {
5
+ registryName;
6
+ knownServices = /* @__PURE__ */ new Set();
7
+ factories = /* @__PURE__ */ new Map();
8
+ instances = /* @__PURE__ */ new Map();
9
+ constructor(registryName, serviceMap, factories) {
10
+ this.registryName = registryName;
11
+ for (const [key, factory] of Object.entries(factories)) {
12
+ const serviceId = serviceMap[key];
13
+ this.knownServices.add(serviceId);
14
+ if (factory !== null) this.factories.set(serviceId, factory);
15
+ }
16
+ }
17
+ async dispose() {
18
+ for (const instance of this.instances.values()) if (Symbol.asyncDispose in instance) await instance[Symbol.asyncDispose]();
19
+ else if (Symbol.dispose in instance) instance[Symbol.dispose]();
20
+ this.instances.clear();
21
+ }
22
+ getById(serviceId) {
23
+ if (!this.knownServices.has(serviceId)) throw new ServiceNotRegisteredError(`Service "${serviceId}" is not registered in ${this.registryName}. Add it to the factory map.`);
24
+ if (this.instances.has(serviceId)) return this.instances.get(serviceId);
25
+ const factory = this.factories.get(serviceId);
26
+ if (!factory) return null;
27
+ const instance = factory();
28
+ this.instances.set(serviceId, instance);
29
+ return instance;
30
+ }
31
+ };
32
+ var ModelServiceRegistry = class extends ServiceRegistryBase {
33
+ constructor(serviceMap, factories) {
34
+ super("ModelServiceRegistry", serviceMap, factories);
35
+ }
36
+ get(id) {
37
+ return this.getById(id);
38
+ }
39
+ };
40
+ var UiServiceRegistry = class extends ServiceRegistryBase {
41
+ constructor(serviceMap, factories) {
42
+ super("UiServiceRegistry", serviceMap, factories);
43
+ }
44
+ get(id) {
45
+ return this.getById(id);
46
+ }
47
+ };
48
+
49
+ //#endregion
50
+ export { ModelServiceRegistry, UiServiceRegistry };
51
+ //# sourceMappingURL=service_registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service_registry.js","names":[],"sources":["../../src/services/service_registry.ts"],"sourcesContent":["import type {\n ServiceTypesLike,\n InferServiceModel,\n InferServiceUi,\n ServiceName,\n ModelServiceFactoryMap,\n UiServiceFactoryMap,\n} from \"./service_types\";\nimport { ServiceNotRegisteredError } from \"../errors\";\nimport type { Services } from \"./service_declarations\";\n\ntype RegistryName = \"ModelServiceRegistry\" | \"UiServiceRegistry\";\ntype ServiceFactory = () => Record<string, Function>;\n\nclass ServiceRegistryBase {\n private readonly registryName: RegistryName;\n private readonly knownServices = new Set<ServiceName>();\n private readonly factories = new Map<ServiceName, ServiceFactory>();\n private readonly instances = new Map<ServiceName, Record<string, Function>>();\n\n protected constructor(\n registryName: RegistryName,\n serviceMap: Record<string, ServiceName>,\n factories: Record<string, (() => unknown) | null>,\n ) {\n this.registryName = registryName;\n for (const [key, factory] of Object.entries(factories)) {\n const serviceId = serviceMap[key];\n this.knownServices.add(serviceId);\n if (factory !== null) {\n this.factories.set(serviceId, factory as ServiceFactory);\n }\n }\n }\n\n async dispose(): Promise<void> {\n for (const instance of this.instances.values()) {\n if (Symbol.asyncDispose in instance) {\n await (instance as AsyncDisposable)[Symbol.asyncDispose]();\n } else if (Symbol.dispose in instance) {\n (instance as Disposable)[Symbol.dispose]();\n }\n }\n this.instances.clear();\n }\n\n protected getById(serviceId: ServiceName): Record<string, Function> | null {\n if (!this.knownServices.has(serviceId)) {\n throw new ServiceNotRegisteredError(\n `Service \"${serviceId}\" is not registered in ${this.registryName}. Add it to the factory map.`,\n );\n }\n if (this.instances.has(serviceId)) return this.instances.get(serviceId)!;\n\n const factory = this.factories.get(serviceId);\n if (!factory) return null;\n\n const instance = factory();\n this.instances.set(serviceId, instance);\n return instance;\n }\n}\n\nexport class ModelServiceRegistry<\n SMap extends Record<string, ServiceName> = typeof Services,\n> extends ServiceRegistryBase {\n constructor(serviceMap: SMap, factories: ModelServiceFactoryMap<SMap>) {\n super(\"ModelServiceRegistry\", serviceMap, factories);\n }\n\n get<S extends ServiceTypesLike>(\n id: ServiceName<S>,\n ):\n | ([unknown] extends [InferServiceModel<S>] ? Record<string, Function> : InferServiceModel<S>)\n | null;\n get(id: ServiceName): Record<string, Function> | null {\n return this.getById(id);\n }\n}\n\nexport class UiServiceRegistry<\n SMap extends Record<string, ServiceName> = typeof Services,\n> extends ServiceRegistryBase {\n constructor(serviceMap: SMap, factories: UiServiceFactoryMap<SMap>) {\n super(\"UiServiceRegistry\", serviceMap, factories);\n }\n\n get<S extends ServiceTypesLike>(\n id: ServiceName<S>,\n ): ([unknown] extends [InferServiceUi<S>] ? Record<string, Function> : InferServiceUi<S>) | null;\n get(id: ServiceName): Record<string, Function> | null {\n return this.getById(id);\n }\n}\n"],"mappings":";;;AAcA,IAAM,sBAAN,MAA0B;CACxB,AAAiB;CACjB,AAAiB,gCAAgB,IAAI,KAAkB;CACvD,AAAiB,4BAAY,IAAI,KAAkC;CACnE,AAAiB,4BAAY,IAAI,KAA4C;CAE7E,AAAU,YACR,cACA,YACA,WACA;AACA,OAAK,eAAe;AACpB,OAAK,MAAM,CAAC,KAAK,YAAY,OAAO,QAAQ,UAAU,EAAE;GACtD,MAAM,YAAY,WAAW;AAC7B,QAAK,cAAc,IAAI,UAAU;AACjC,OAAI,YAAY,KACd,MAAK,UAAU,IAAI,WAAW,QAA0B;;;CAK9D,MAAM,UAAyB;AAC7B,OAAK,MAAM,YAAY,KAAK,UAAU,QAAQ,CAC5C,KAAI,OAAO,gBAAgB,SACzB,OAAO,SAA6B,OAAO,eAAe;WACjD,OAAO,WAAW,SAC3B,CAAC,SAAwB,OAAO,UAAU;AAG9C,OAAK,UAAU,OAAO;;CAGxB,AAAU,QAAQ,WAAyD;AACzE,MAAI,CAAC,KAAK,cAAc,IAAI,UAAU,CACpC,OAAM,IAAI,0BACR,YAAY,UAAU,yBAAyB,KAAK,aAAa,8BAClE;AAEH,MAAI,KAAK,UAAU,IAAI,UAAU,CAAE,QAAO,KAAK,UAAU,IAAI,UAAU;EAEvE,MAAM,UAAU,KAAK,UAAU,IAAI,UAAU;AAC7C,MAAI,CAAC,QAAS,QAAO;EAErB,MAAM,WAAW,SAAS;AAC1B,OAAK,UAAU,IAAI,WAAW,SAAS;AACvC,SAAO;;;AAIX,IAAa,uBAAb,cAEU,oBAAoB;CAC5B,YAAY,YAAkB,WAAyC;AACrE,QAAM,wBAAwB,YAAY,UAAU;;CAQtD,IAAI,IAAkD;AACpD,SAAO,KAAK,QAAQ,GAAG;;;AAI3B,IAAa,oBAAb,cAEU,oBAAoB;CAC5B,YAAY,YAAkB,WAAsC;AAClE,QAAM,qBAAqB,YAAY,UAAU;;CAMnD,IAAI,IAAkD;AACpD,SAAO,KAAK,QAAQ,GAAG"}
@@ -0,0 +1,30 @@
1
+ const require_errors = require('../errors.cjs');
2
+
3
+ //#region src/services/service_types.ts
4
+ const SERVICE_ID_PATTERN = /^[a-zA-Z][a-zA-Z0-9]*$/;
5
+ const { service, isNodeService } = (() => {
6
+ const typeMap = /* @__PURE__ */ new Map();
7
+ return {
8
+ service() {
9
+ return (options) => {
10
+ const { name, type } = options;
11
+ if (!SERVICE_ID_PATTERN.test(name)) throw new require_errors.ServiceInvalidIdError(`Invalid service ID "${name}": must match ${SERVICE_ID_PATTERN}`);
12
+ if (typeMap.has(name)) throw new require_errors.ServiceAlreadyRegisteredError(`Service "${name}" already registered`);
13
+ typeMap.set(name, type);
14
+ return name;
15
+ };
16
+ },
17
+ isNodeService(id) {
18
+ return typeMap.get(id) === "node";
19
+ }
20
+ };
21
+ })();
22
+ function serviceFnKey(serviceId, method = "") {
23
+ return `service:${serviceId}:${method}`;
24
+ }
25
+
26
+ //#endregion
27
+ exports.isNodeService = isNodeService;
28
+ exports.service = service;
29
+ exports.serviceFnKey = serviceFnKey;
30
+ //# sourceMappingURL=service_types.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service_types.cjs","names":["ServiceInvalidIdError","ServiceAlreadyRegisteredError"],"sources":["../../src/services/service_types.ts"],"sourcesContent":["import type { Branded } from \"../branding\";\nimport { ServiceAlreadyRegisteredError, ServiceInvalidIdError } from \"../errors\";\nimport type { Services } from \"./service_declarations\";\n\nexport type ServiceTypesLike<\n Model = unknown,\n Ui = unknown,\n Kind extends ServiceType = ServiceType,\n> = {\n readonly __types?: { model: Model; ui: Ui; kind: Kind };\n};\n\nexport type InferServiceModel<S extends ServiceTypesLike> =\n S extends ServiceTypesLike<infer M, unknown, ServiceType> ? M : unknown;\n\nexport type InferServiceUi<S extends ServiceTypesLike> =\n S extends ServiceTypesLike<unknown, infer U, ServiceType> ? U : unknown;\n\nexport type InferServiceKind<S extends ServiceTypesLike> =\n S extends ServiceTypesLike<unknown, unknown, infer K> ? K : ServiceType;\n\nexport type ServiceName<S extends ServiceTypesLike = ServiceTypesLike> = Branded<string, S>;\n\nexport type ServiceType = \"node\" | \"wasm\";\n\nconst SERVICE_ID_PATTERN = /^[a-zA-Z][a-zA-Z0-9]*$/;\n\nexport const { service, isNodeService } = (() => {\n const typeMap = new Map<string, ServiceType>();\n return {\n service<Model, Ui>() {\n return <K extends ServiceType, N extends string>(options: {\n readonly type: K;\n readonly name: N;\n }): Branded<N, ServiceTypesLike<Model, Ui, K>> => {\n const { name, type } = options;\n if (!SERVICE_ID_PATTERN.test(name)) {\n throw new ServiceInvalidIdError(\n `Invalid service ID \"${name}\": must match ${SERVICE_ID_PATTERN}`,\n );\n }\n if (typeMap.has(name)) {\n throw new ServiceAlreadyRegisteredError(`Service \"${name}\" already registered`);\n }\n typeMap.set(name, type);\n return name as Branded<N, ServiceTypesLike<Model, Ui, K>>;\n };\n },\n isNodeService(id: ServiceName): boolean {\n return typeMap.get(id) === \"node\";\n },\n };\n})();\n\nexport function serviceFnKey(serviceId: string, method = \"\"): string {\n return `service:${serviceId}:${method}`;\n}\n\nexport type ServiceBrand<T> =\n T extends Branded<string, infer S extends ServiceTypesLike> ? S : never;\n\nexport type ModelServiceFactoryMap<SMap extends Record<string, ServiceName>> = {\n [K in keyof SMap]: (() => InferServiceModel<ServiceBrand<SMap[K]>>) | null;\n};\n\nexport type UiServiceFactoryMap<SMap extends Record<string, ServiceName>> = {\n [K in keyof SMap]: (() => InferServiceUi<ServiceBrand<SMap[K]>>) | null;\n};\n\n/** Contract between any service provider and any service consumer. */\nexport interface ServiceDispatch {\n getServiceNames(): ServiceName[];\n getServiceMethods(serviceId: ServiceName): string[];\n callServiceMethod(serviceId: ServiceName, method: string, ...args: unknown[]): unknown;\n}\n\n// Auto-derived types from the Services const in service_declarations.ts.\n// Adding a service to Services automatically updates all of these.\n\ntype SMap = typeof Services;\n\ntype ExtractServiceName<T> = T extends Branded<infer N extends string, any> ? N : never;\n\n/** Model-side service interfaces keyed by service name literal. */\nexport type ModelServices = {\n [K in keyof SMap as ExtractServiceName<SMap[K]>]: InferServiceModel<ServiceBrand<SMap[K]>>;\n};\n\n/** UI-side service interfaces keyed by service name literal. */\nexport type UiServices = {\n [K in keyof SMap as ExtractServiceName<SMap[K]>]: InferServiceUi<ServiceBrand<SMap[K]>>;\n};\n\n/** Map from Services keys to their unbranded string name literals. */\nexport type ServiceNameLiterals = {\n [K in keyof SMap]: ExtractServiceName<SMap[K]>;\n};\n\n/** Auto-derived requires* feature flags from Services keys. */\nexport type ServiceRequireFlags = {\n [K in keyof SMap as `requires${K & string}`]?: boolean;\n};\n\ntype UnionToIntersection<U> = (U extends unknown ? (k: U) => void : never) extends (\n k: infer I,\n) => void\n ? I\n : never;\n\nexport type RequireServices<T extends ServiceName> = UnionToIntersection<\n T extends Branded<infer N extends string, infer S extends ServiceTypesLike>\n ? Record<N, InferServiceModel<S>>\n : never\n>;\n"],"mappings":";;;AAyBA,MAAM,qBAAqB;AAE3B,MAAa,EAAE,SAAS,yBAAyB;CAC/C,MAAM,0BAAU,IAAI,KAA0B;AAC9C,QAAO;EACL,UAAqB;AACnB,WAAiD,YAGC;IAChD,MAAM,EAAE,MAAM,SAAS;AACvB,QAAI,CAAC,mBAAmB,KAAK,KAAK,CAChC,OAAM,IAAIA,qCACR,uBAAuB,KAAK,gBAAgB,qBAC7C;AAEH,QAAI,QAAQ,IAAI,KAAK,CACnB,OAAM,IAAIC,6CAA8B,YAAY,KAAK,sBAAsB;AAEjF,YAAQ,IAAI,MAAM,KAAK;AACvB,WAAO;;;EAGX,cAAc,IAA0B;AACtC,UAAO,QAAQ,IAAI,GAAG,KAAK;;EAE9B;IACC;AAEJ,SAAgB,aAAa,WAAmB,SAAS,IAAY;AACnE,QAAO,WAAW,UAAU,GAAG"}
@@ -0,0 +1,45 @@
1
+ import { Branded } from "../branding.js";
2
+ import { Services } from "./service_declarations.js";
3
+
4
+ //#region src/services/service_types.d.ts
5
+ type ServiceTypesLike<Model = unknown, Ui = unknown, Kind extends ServiceType = ServiceType> = {
6
+ readonly __types?: {
7
+ model: Model;
8
+ ui: Ui;
9
+ kind: Kind;
10
+ };
11
+ };
12
+ type InferServiceModel<S extends ServiceTypesLike> = S extends ServiceTypesLike<infer M, unknown, ServiceType> ? M : unknown;
13
+ type InferServiceUi<S extends ServiceTypesLike> = S extends ServiceTypesLike<unknown, infer U, ServiceType> ? U : unknown;
14
+ type InferServiceKind<S extends ServiceTypesLike> = S extends ServiceTypesLike<unknown, unknown, infer K> ? K : ServiceType;
15
+ type ServiceName<S extends ServiceTypesLike = ServiceTypesLike> = Branded<string, S>;
16
+ type ServiceType = "node" | "wasm";
17
+ declare const service: <Model, Ui>() => <K extends ServiceType, N extends string>(options: {
18
+ readonly type: K;
19
+ readonly name: N;
20
+ }) => Branded<N, ServiceTypesLike<Model, Ui, K>>, isNodeService: (id: ServiceName) => boolean;
21
+ declare function serviceFnKey(serviceId: string, method?: string): string;
22
+ type ServiceBrand<T> = T extends Branded<string, infer S extends ServiceTypesLike> ? S : never;
23
+ type ModelServiceFactoryMap<SMap extends Record<string, ServiceName>> = { [K in keyof SMap]: (() => InferServiceModel<ServiceBrand<SMap[K]>>) | null };
24
+ type UiServiceFactoryMap<SMap extends Record<string, ServiceName>> = { [K in keyof SMap]: (() => InferServiceUi<ServiceBrand<SMap[K]>>) | null };
25
+ /** Contract between any service provider and any service consumer. */
26
+ interface ServiceDispatch {
27
+ getServiceNames(): ServiceName[];
28
+ getServiceMethods(serviceId: ServiceName): string[];
29
+ callServiceMethod(serviceId: ServiceName, method: string, ...args: unknown[]): unknown;
30
+ }
31
+ type SMap = typeof Services;
32
+ type ExtractServiceName<T> = T extends Branded<infer N extends string, any> ? N : never;
33
+ /** Model-side service interfaces keyed by service name literal. */
34
+ type ModelServices = { [K in keyof SMap as ExtractServiceName<SMap[K]>]: InferServiceModel<ServiceBrand<SMap[K]>> };
35
+ /** UI-side service interfaces keyed by service name literal. */
36
+ type UiServices = { [K in keyof SMap as ExtractServiceName<SMap[K]>]: InferServiceUi<ServiceBrand<SMap[K]>> };
37
+ /** Map from Services keys to their unbranded string name literals. */
38
+ type ServiceNameLiterals = { [K in keyof SMap]: ExtractServiceName<SMap[K]> };
39
+ /** Auto-derived requires* feature flags from Services keys. */
40
+ type ServiceRequireFlags = { [K in keyof SMap as `requires${K & string}`]?: boolean };
41
+ type UnionToIntersection<U> = (U extends unknown ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;
42
+ type RequireServices<T extends ServiceName> = UnionToIntersection<T extends Branded<infer N extends string, infer S extends ServiceTypesLike> ? Record<N, InferServiceModel<S>> : never>;
43
+ //#endregion
44
+ export { InferServiceKind, InferServiceModel, InferServiceUi, ModelServiceFactoryMap, ModelServices, RequireServices, ServiceBrand, ServiceDispatch, ServiceName, ServiceNameLiterals, ServiceRequireFlags, ServiceType, ServiceTypesLike, UiServiceFactoryMap, UiServices, isNodeService, service, serviceFnKey };
45
+ //# sourceMappingURL=service_types.d.ts.map
@@ -0,0 +1,28 @@
1
+ import { ServiceAlreadyRegisteredError, ServiceInvalidIdError } from "../errors.js";
2
+
3
+ //#region src/services/service_types.ts
4
+ const SERVICE_ID_PATTERN = /^[a-zA-Z][a-zA-Z0-9]*$/;
5
+ const { service, isNodeService } = (() => {
6
+ const typeMap = /* @__PURE__ */ new Map();
7
+ return {
8
+ service() {
9
+ return (options) => {
10
+ const { name, type } = options;
11
+ if (!SERVICE_ID_PATTERN.test(name)) throw new ServiceInvalidIdError(`Invalid service ID "${name}": must match ${SERVICE_ID_PATTERN}`);
12
+ if (typeMap.has(name)) throw new ServiceAlreadyRegisteredError(`Service "${name}" already registered`);
13
+ typeMap.set(name, type);
14
+ return name;
15
+ };
16
+ },
17
+ isNodeService(id) {
18
+ return typeMap.get(id) === "node";
19
+ }
20
+ };
21
+ })();
22
+ function serviceFnKey(serviceId, method = "") {
23
+ return `service:${serviceId}:${method}`;
24
+ }
25
+
26
+ //#endregion
27
+ export { isNodeService, service, serviceFnKey };
28
+ //# sourceMappingURL=service_types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service_types.js","names":[],"sources":["../../src/services/service_types.ts"],"sourcesContent":["import type { Branded } from \"../branding\";\nimport { ServiceAlreadyRegisteredError, ServiceInvalidIdError } from \"../errors\";\nimport type { Services } from \"./service_declarations\";\n\nexport type ServiceTypesLike<\n Model = unknown,\n Ui = unknown,\n Kind extends ServiceType = ServiceType,\n> = {\n readonly __types?: { model: Model; ui: Ui; kind: Kind };\n};\n\nexport type InferServiceModel<S extends ServiceTypesLike> =\n S extends ServiceTypesLike<infer M, unknown, ServiceType> ? M : unknown;\n\nexport type InferServiceUi<S extends ServiceTypesLike> =\n S extends ServiceTypesLike<unknown, infer U, ServiceType> ? U : unknown;\n\nexport type InferServiceKind<S extends ServiceTypesLike> =\n S extends ServiceTypesLike<unknown, unknown, infer K> ? K : ServiceType;\n\nexport type ServiceName<S extends ServiceTypesLike = ServiceTypesLike> = Branded<string, S>;\n\nexport type ServiceType = \"node\" | \"wasm\";\n\nconst SERVICE_ID_PATTERN = /^[a-zA-Z][a-zA-Z0-9]*$/;\n\nexport const { service, isNodeService } = (() => {\n const typeMap = new Map<string, ServiceType>();\n return {\n service<Model, Ui>() {\n return <K extends ServiceType, N extends string>(options: {\n readonly type: K;\n readonly name: N;\n }): Branded<N, ServiceTypesLike<Model, Ui, K>> => {\n const { name, type } = options;\n if (!SERVICE_ID_PATTERN.test(name)) {\n throw new ServiceInvalidIdError(\n `Invalid service ID \"${name}\": must match ${SERVICE_ID_PATTERN}`,\n );\n }\n if (typeMap.has(name)) {\n throw new ServiceAlreadyRegisteredError(`Service \"${name}\" already registered`);\n }\n typeMap.set(name, type);\n return name as Branded<N, ServiceTypesLike<Model, Ui, K>>;\n };\n },\n isNodeService(id: ServiceName): boolean {\n return typeMap.get(id) === \"node\";\n },\n };\n})();\n\nexport function serviceFnKey(serviceId: string, method = \"\"): string {\n return `service:${serviceId}:${method}`;\n}\n\nexport type ServiceBrand<T> =\n T extends Branded<string, infer S extends ServiceTypesLike> ? S : never;\n\nexport type ModelServiceFactoryMap<SMap extends Record<string, ServiceName>> = {\n [K in keyof SMap]: (() => InferServiceModel<ServiceBrand<SMap[K]>>) | null;\n};\n\nexport type UiServiceFactoryMap<SMap extends Record<string, ServiceName>> = {\n [K in keyof SMap]: (() => InferServiceUi<ServiceBrand<SMap[K]>>) | null;\n};\n\n/** Contract between any service provider and any service consumer. */\nexport interface ServiceDispatch {\n getServiceNames(): ServiceName[];\n getServiceMethods(serviceId: ServiceName): string[];\n callServiceMethod(serviceId: ServiceName, method: string, ...args: unknown[]): unknown;\n}\n\n// Auto-derived types from the Services const in service_declarations.ts.\n// Adding a service to Services automatically updates all of these.\n\ntype SMap = typeof Services;\n\ntype ExtractServiceName<T> = T extends Branded<infer N extends string, any> ? N : never;\n\n/** Model-side service interfaces keyed by service name literal. */\nexport type ModelServices = {\n [K in keyof SMap as ExtractServiceName<SMap[K]>]: InferServiceModel<ServiceBrand<SMap[K]>>;\n};\n\n/** UI-side service interfaces keyed by service name literal. */\nexport type UiServices = {\n [K in keyof SMap as ExtractServiceName<SMap[K]>]: InferServiceUi<ServiceBrand<SMap[K]>>;\n};\n\n/** Map from Services keys to their unbranded string name literals. */\nexport type ServiceNameLiterals = {\n [K in keyof SMap]: ExtractServiceName<SMap[K]>;\n};\n\n/** Auto-derived requires* feature flags from Services keys. */\nexport type ServiceRequireFlags = {\n [K in keyof SMap as `requires${K & string}`]?: boolean;\n};\n\ntype UnionToIntersection<U> = (U extends unknown ? (k: U) => void : never) extends (\n k: infer I,\n) => void\n ? I\n : never;\n\nexport type RequireServices<T extends ServiceName> = UnionToIntersection<\n T extends Branded<infer N extends string, infer S extends ServiceTypesLike>\n ? Record<N, InferServiceModel<S>>\n : never\n>;\n"],"mappings":";;;AAyBA,MAAM,qBAAqB;AAE3B,MAAa,EAAE,SAAS,yBAAyB;CAC/C,MAAM,0BAAU,IAAI,KAA0B;AAC9C,QAAO;EACL,UAAqB;AACnB,WAAiD,YAGC;IAChD,MAAM,EAAE,MAAM,SAAS;AACvB,QAAI,CAAC,mBAAmB,KAAK,KAAK,CAChC,OAAM,IAAI,sBACR,uBAAuB,KAAK,gBAAgB,qBAC7C;AAEH,QAAI,QAAQ,IAAI,KAAK,CACnB,OAAM,IAAI,8BAA8B,YAAY,KAAK,sBAAsB;AAEjF,YAAQ,IAAI,MAAM,KAAK;AACvB,WAAO;;;EAGX,cAAc,IAA0B;AACtC,UAAO,QAAQ,IAAI,GAAG,KAAK;;EAE9B;IACC;AAEJ,SAAgB,aAAa,WAAmB,SAAS,IAAY;AACnE,QAAO,WAAW,UAAU,GAAG"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@milaboratories/pl-model-common",
3
- "version": "1.29.0",
3
+ "version": "1.31.0",
4
4
  "description": "Platforma SDK Model",
5
5
  "files": [
6
6
  "./dist/**/*",
@@ -19,15 +19,15 @@
19
19
  "dependencies": {
20
20
  "canonicalize": "~2.1.0",
21
21
  "zod": "~3.23.8",
22
- "@milaboratories/helpers": "1.14.0",
23
- "@milaboratories/pl-error-like": "1.12.9"
22
+ "@milaboratories/pl-error-like": "1.12.9",
23
+ "@milaboratories/helpers": "1.14.0"
24
24
  },
25
25
  "devDependencies": {
26
26
  "@vitest/coverage-istanbul": "^4.0.18",
27
27
  "typescript": "~5.9.3",
28
28
  "vitest": "^4.0.18",
29
- "@milaboratories/build-configs": "1.5.2",
30
29
  "@milaboratories/ts-builder": "1.3.0",
30
+ "@milaboratories/build-configs": "1.5.2",
31
31
  "@milaboratories/ts-configs": "1.2.2"
32
32
  },
33
33
  "scripts": {