@camstack/server 1.1.39 → 1.1.41

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.
@@ -11,9 +11,6 @@
11
11
  * - `concatCollection(providers, method)` — collection caps whose
12
12
  * methods return arrays and where the desired behaviour is "union of
13
13
  * every provider's contribution" (e.g. `turn-provider.getTurnServers`).
14
- * - `firstSupported(providers, probe, action)` — collection caps where
15
- * exactly one provider should handle each request, selected by a
16
- * probe method (e.g. `snapshot-provider.supportsDevice`).
17
14
  *
18
15
  * Collections that route by an input key (e.g. `webrtc` picking the
19
16
  * provider responsible for a given `streamId`) are NOT covered here —
@@ -23,8 +20,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
23
20
  exports.requireSingleton = requireSingleton;
24
21
  exports.requireDeviceScoped = requireDeviceScoped;
25
22
  exports.concatCollection = concatCollection;
26
- exports.firstSupported = firstSupported;
27
- exports.anySupports = anySupports;
28
23
  const server_1 = require("@trpc/server");
29
24
  /**
30
25
  * Fetch the currently active singleton provider for a capability.
@@ -128,61 +123,3 @@ function concatCollection(providers, method) {
128
123
  // boundary assertion is required.
129
124
  return wrapper;
130
125
  }
131
- /**
132
- * Iterate a collection asking each provider "do you handle this?" via a
133
- * probe method, then call an action on the first one that answers yes.
134
- * Each provider is tried in registration order; errors are swallowed and
135
- * the next provider is attempted. Returns null if no provider matches or
136
- * if every matching provider's action throws/returns null.
137
- */
138
- function firstSupported(providers, probe, action) {
139
- const wrapper = async (...args) => {
140
- const [first] = args;
141
- for (const p of providers) {
142
- try {
143
- const probeMember = Reflect.get(p, probe);
144
- if (typeof probeMember !== 'function')
145
- continue;
146
- const supported = await Reflect.apply(probeMember, p, [first]);
147
- if (supported !== true)
148
- continue;
149
- const actionMember = Reflect.get(p, action);
150
- if (typeof actionMember !== 'function')
151
- continue;
152
- const result = await Reflect.apply(actionMember, p, args);
153
- if (result !== null && result !== undefined)
154
- return result;
155
- }
156
- catch {
157
- // try next provider
158
- }
159
- }
160
- return null;
161
- };
162
- // Type-level bridge — see concatCollection for the same pattern.
163
- return wrapper;
164
- }
165
- /**
166
- * Convenience for collection caps that want a "logical OR of probes"
167
- * (e.g. `supportsDevice` across every snapshot-provider).
168
- */
169
- function anySupports(providers, probe) {
170
- const wrapper = async (...args) => {
171
- for (const p of providers) {
172
- const member = Reflect.get(p, probe);
173
- if (typeof member !== 'function')
174
- continue;
175
- try {
176
- const result = await Reflect.apply(member, p, args);
177
- if (result === true)
178
- return true;
179
- }
180
- catch {
181
- /* next */
182
- }
183
- }
184
- return false;
185
- };
186
- // Type-level bridge — see concatCollection for the same pattern.
187
- return wrapper;
188
- }
@@ -14,10 +14,10 @@
14
14
  * kind), the cross-node `remoteProxy`, and the canonical tRPC error
15
15
  * raisers (the server owns `TRPCError`).
16
16
  *
17
- * The result is spread into the AppRouter BEFORE the hand-written core
18
- * routers + the `custom`-mount overrides (snapshot-provider, webrtc-
19
- * session), so override-by-spread precedence is preserved exactly as it
20
- * was with the old static `mountAllCaps()` spread.
17
+ * The result is spread into the AppRouter alongside the hand-written core
18
+ * (non-cap) routers. Every cap is built here from the live def; the server
19
+ * supplies `server-provided` provider factories (incl. webrtc-session) via the
20
+ * `serverProviders` map no hand-written cap-router override remains.
21
21
  */
22
22
  Object.defineProperty(exports, "__esModule", { value: true });
23
23
  exports.COLLECTION_ARRAY_METHODS = void 0;
@@ -46,7 +46,7 @@ function computeArrayMethods() {
46
46
  const m = schema;
47
47
  if (m.kind === 'subscription')
48
48
  continue;
49
- if (isArrayOutputSchema(m.output))
49
+ if ((0, types_1.isArrayOutputSchema)(m.output))
50
50
  names.push(name);
51
51
  }
52
52
  if (names.length > 0)
@@ -54,32 +54,6 @@ function computeArrayMethods() {
54
54
  }
55
55
  return out;
56
56
  }
57
- /**
58
- * Structural "is this Zod schema an array output" check — bottoms out at
59
- * `ZodArray` through the canonical Zod 4 wrappers. Identical logic to
60
- * `scripts/generate-cap-mounts.ts`.
61
- */
62
- function isArrayOutputSchema(schema) {
63
- let cur = schema;
64
- for (let depth = 0; depth < 8 && cur != null; depth += 1) {
65
- const def = cur._def;
66
- const ctor = cur.constructor?.name;
67
- if (ctor === 'ZodArray' || def?.type === 'array')
68
- return true;
69
- const wraps = ctor === 'ZodReadonly' ||
70
- def?.type === 'readonly' ||
71
- ctor === 'ZodOptional' ||
72
- def?.type === 'optional' ||
73
- ctor === 'ZodNullable' ||
74
- def?.type === 'nullable' ||
75
- ctor === 'ZodDefault' ||
76
- def?.type === 'default';
77
- if (!wraps || def?.innerType == null)
78
- return false;
79
- cur = def.innerType;
80
- }
81
- return false;
82
- }
83
57
  /**
84
58
  * Resolve a collection cap's provider exactly as the codegen-emitted
85
59
  * mount did:
@@ -158,8 +132,12 @@ function createCapRouterServices(deps) {
158
132
  const remoteProxy = (capName, nodeId) => deps.moleculer.createCapabilityProxy(capName, nodeId);
159
133
  const getLocalProvider = (capName, mountKind, ctx, addonId) => {
160
134
  switch (mountKind) {
161
- case 'service-backed': {
162
- const factory = deps.serviceProviders[capName];
135
+ // `service-backed` is the pre-SP1 name for `server-provided`; accept both
136
+ // so a framework-live-update version skew (old types on new server, or a
137
+ // future rollback) can't drop these caps into the singleton `default`.
138
+ case 'service-backed':
139
+ case 'server-provided': {
140
+ const factory = deps.serverProviders[capName];
163
141
  return factory ? factory(ctx) : null;
164
142
  }
165
143
  case 'device-native':
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isCoreServiceCapName = isCoreServiceCapName;
3
4
  exports.buildCoreCapService = buildCoreCapService;
4
5
  const system_1 = require("@camstack/system");
5
6
  const trpc_middleware_js_1 = require("./trpc.middleware.js");
@@ -43,6 +44,27 @@ const CORE_NAMESPACES = new Set([
43
44
  function toKebab(name) {
44
45
  return name.replace(/[A-Z]/g, (m, i) => (i > 0 ? '-' : '') + m.toLowerCase());
45
46
  }
47
+ /**
48
+ * Every hub-core cap NAME as it can arrive on the wire — both the appRouter
49
+ * namespace (`streamProbe`) and its kebab form (`stream-probe`, the cap
50
+ * definition `name`). {@link isCoreServiceCapName} checks membership.
51
+ */
52
+ const CORE_CAP_NAMES = new Set([
53
+ ...CORE_NAMESPACES,
54
+ ...[...CORE_NAMESPACES].map(toKebab),
55
+ ]);
56
+ /**
57
+ * True when `capName` is a hub-core `$`-service cap (served by `$core-caps` /
58
+ * the hand-written core routers, NOT by any addon provider). The `onUnownedCall`
59
+ * handler uses this as the SINGLE discriminant for its broker fallback: a
60
+ * resolver miss on a core cap is legitimately routed via the broker; a miss on
61
+ * anything else means an addon provider is not registered yet. Derived from the
62
+ * already-maintained {@link CORE_NAMESPACES} — a new addon cap is covered with
63
+ * zero changes here.
64
+ */
65
+ function isCoreServiceCapName(capName) {
66
+ return CORE_CAP_NAMES.has(capName);
67
+ }
46
68
  function isProcedureNode(value) {
47
69
  // A built tRPC procedure is a callable object — `_def.procedures`
48
70
  // stores the procedure function directly, not a wrapper object.
@@ -2,7 +2,7 @@
2
2
  // AUTO-GENERATED by scripts/generate-cap-mounts.ts — DO NOT EDIT
3
3
  // Re-run: npx tsx scripts/generate-cap-mounts.ts
4
4
  //
5
- // Mounted: 133 Skipped (legacy): 6
5
+ // Mounted: 132 Skipped (legacy): 3
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
7
  exports.LEGACY_SHAPE_SKIP = void 0;
8
8
  exports.mountAllCaps = mountAllCaps;
@@ -19,9 +19,6 @@ exports.LEGACY_SHAPE_SKIP = new Set([
19
19
  'addonRoutes',
20
20
  'authProvider',
21
21
  'logDestination',
22
- 'restreamer',
23
- 'streamingEngine',
24
- 'webrtc',
25
22
  ]);
26
23
  /**
27
24
  * Build the auto-mount map. `services` carries the registry handle
@@ -326,15 +323,6 @@ function mountAllCaps(services) {
326
323
  return entries[0]?.[1] ?? null;
327
324
  }, remoteCapProxy),
328
325
  snapshot: (0, generated_cap_routers_js_1.createCapRouter_snapshot)((_ctx) => (0, cap_mount_helpers_js_1.requireDeviceScoped)(reg, 'snapshot'), remoteCapProxy),
329
- snapshotProvider: (0, generated_cap_routers_js_1.createCapRouter_snapshotProvider)((_ctx, addonId) => {
330
- if (!reg)
331
- return null;
332
- if (addonId !== undefined) {
333
- return reg.getProviderByAddonId('snapshot-provider', addonId);
334
- }
335
- const entries = reg.getCollectionEntries('snapshot-provider');
336
- return entries[0]?.[1] ?? null;
337
- }, remoteCapProxy),
338
326
  ssoBridge: (0, generated_cap_routers_js_1.createCapRouter_ssoBridge)((_ctx) => reg?.getSingleton('sso-bridge') ?? null, remoteCapProxy),
339
327
  storage: (0, generated_cap_routers_js_1.createCapRouter_storage)((_ctx) => reg?.getSingleton('storage') ?? null, remoteCapProxy),
340
328
  storageEvictable: (0, generated_cap_routers_js_1.createCapRouter_storageEvictable)((_ctx, addonId) => {