@neta-art/cohub 5.9.0 → 6.0.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.
- package/README.md +42 -46
- package/dist/board/animation.d.ts +156 -67
- package/dist/board/animation.js +162 -277
- package/dist/board/codec.js +1 -1
- package/dist/board/export/index.d.ts +6 -0
- package/dist/board/export/index.js +6 -3
- package/dist/board/export/scene.d.ts +6 -0
- package/dist/board/export/scene.js +26 -2
- package/dist/board/geometry.d.ts +27 -1
- package/dist/board/geometry.js +92 -1
- package/dist/board/headless/index.d.ts +7 -1
- package/dist/board/headless/index.js +6 -2
- package/dist/board/index.d.ts +8 -6
- package/dist/board/index.js +7 -6
- package/dist/board/mutation.d.ts +15 -0
- package/dist/board/mutation.js +67 -0
- package/dist/board/render/css-color.d.ts +4 -0
- package/dist/board/render/css-color.js +36 -0
- package/dist/board/render/index.d.ts +2 -1
- package/dist/board/render/index.js +2 -1
- package/dist/board/render/renderers/base-card-renderer.js +3 -20
- package/dist/board/render/themes/clean-theme.js +6 -3
- package/dist/chunks/http.d.ts +30 -7
- package/dist/chunks/http.js +785 -289
- package/dist/chunks/websocket.d.ts +2675 -187
- package/dist/http.d.ts +3 -3
- package/dist/index.d.ts +158 -299
- package/dist/index.js +164 -279
- package/dist/protocol/dist/board-authoring.d.ts +1 -0
- package/dist/protocol/dist/board-authoring.js +217 -0
- package/dist/protocol/dist/board-capability-registry.d.ts +2 -0
- package/dist/protocol/dist/board-capability-registry.js +74 -0
- package/dist/protocol/dist/board-codec.d.ts +2 -0
- package/dist/protocol/dist/board-codec.js +4 -0
- package/dist/protocol/dist/board-composition.d.ts +258 -0
- package/dist/protocol/dist/board-composition.js +318 -0
- package/dist/protocol/dist/board-constants.d.ts +2 -1
- package/dist/protocol/dist/board-constants.js +40 -10
- package/dist/protocol/dist/board-document.d.ts +28 -2
- package/dist/protocol/dist/board-document.js +16 -3
- package/dist/protocol/dist/board-node.d.ts +1 -11
- package/dist/protocol/dist/board-node.js +1 -81
- package/dist/protocol/dist/board-upgrade.d.ts +1 -0
- package/dist/protocol/dist/board-upgrade.js +2 -0
- package/dist/protocol/dist/board-url.d.ts +2 -1
- package/dist/protocol/dist/board-url.js +8 -3
- package/dist/protocol/dist/board.d.ts +135 -76
- package/dist/protocol/dist/board.js +50 -69
- package/dist/protocol/dist/index.d.ts +9 -4
- package/dist/protocol/dist/index.js +9 -4
- package/dist/types.d.ts +3 -2
- package/docs/work-runtime-guide.md +19 -3
- package/package.json +3 -2
- package/dist/board/nodes.d.ts +0 -113
- package/dist/board/nodes.js +0 -154
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as
|
|
1
|
+
import { $ as BOARD_GEO_KINDS, A as buildWorkComposerChipSet, B as UI_COMMAND_MAX_TIMEOUT_MS, C as ensureRealtimeConnected, Ct as SkillsApi, D as WORK_SURFACE_READY_TIMEOUT_MS, Dt as CronJobsApi, E as WORK_COMPOSER_CHIP_LABEL_MAX_LENGTH, Et as GenerationsApi, F as parseWorkComposerChipSet, G as UI_COMMAND_VERSION, H as UI_COMMAND_PENDING_TTL_SECONDS, I as parseWorkSurfaceReady, J as parseUiCommand, K as isTerminalUiCommandStatus, L as parseWorkSurfaceRequest, M as buildWorkSurfaceRequest, N as buildWorkSurfaceResponse, O as WORK_SURFACE_REQUEST_TIMEOUT_MS, Ot as ChannelsApi, P as parseWorkComposerChipClear, Q as BOARD_COLOR_IDS, R as parseWorkSurfaceResponse, S as createSessionPatchReducer, St as PublicAssetsApi, T as WORK_COMPOSER_CHIP_KEY_MAX_LENGTH, Tt as ModelsApi, U as UI_COMMAND_SETTLEMENT_GRACE_SECONDS, V as UI_COMMAND_PAYLOAD_MAX_BYTES, W as UI_COMMAND_TERMINAL_TTL_SECONDS, X as parseUsername, Y as parseSpaceSlug, Z as BoardAwarenessClientPayloadSchema, _ as buildSpacePath, _t as BOARD_BUILTIN_CAPABILITIES, a as ReferralsApi, at as BoardEffectSchema, b as parseAssistantMessageCommit, bt as ReferencesApi, c as UiCommandsApi, ct as BoardAuthoringItemSchema, d as BoardTransactionError, dt as BOARD_ANIMATION_CHANNEL_CAPABILITIES, et as BOARD_NATIVE_NODE_TYPES, f as SpaceClient, ft as BoardCompositionInputSchema, g as buildSpaceInvitePath, gt as parseBoardCompositionInput, h as PublicInviteApi, ht as BoardTrackSchema, i as WorksApi, it as validateBuiltinBoardClip, j as buildWorkSurfaceReady, k as buildWorkComposerChipClear, l as TasksApi, lt as BoardItemPatchSchema, m as SpacesApi, mt as BoardProceduralClipSchema, n as createHttpClient, nt as validateBoardNodeInput, o as UsersApi, ot as BoardPlaybackPolicySchema, p as SpacePublicFilesApi, pt as BoardCompositionSchema, q as isUiSurfaceMethod, r as WorkCommerceApi, rt as estimateBuiltinBoardClipCost, s as UserApi, st as parseBoardPlaybackPolicy, t as CohubHttpClient, tt as BOARD_NODE_CONTRACT, u as BoardClient, ut as BOARD_ANIMATION_CHANNELS, v as SessionGenerationStreamClient, vt as DEFAULT_BOARD_RENDER_LIMITS, w as WORK_COMPOSER_CHIP_CONTENT_MAX_BYTES, wt as PromptsApi, x as SessionPatchReducer, xt as SearchApi, y as createSessionGenerationStreamClient, yt as SessionAccessApi, z as UI_COMMAND_DEFAULT_TIMEOUT_MS } from "./chunks/http.js";
|
|
2
2
|
import { _ as requestSourceToHeaders, a as sanitizeAccessToken, b as REALTIME_DOMAINS, c as REQUEST_SOURCE_VIA_MAX_LENGTH, d as isRequestSourceEmpty, f as isRequestSourceUuid, g as readRequestSourceFromEnv, h as parseRequestSourceFromHeaders, i as matchesUnauthorizedErrorToken, l as hasRequestSourceIdentity, m as normalizeRequestSource, n as HttpTransport, o as COHUB_SOURCE_HEADER, p as mergeRequestSourceIntoMeta, r as joinApiUrl, s as COHUB_SOURCE_HEADER_NAMES, t as HttpError, u as isRequestSourceClientId, v as resolveRequestSourceChannel, x as REALTIME_ROOM_EVENT_NAME_PATTERN, y as isUuid } from "./chunks/transport.js";
|
|
3
3
|
import { a as resolveApiBaseUrl, c as resolveWebsocketUrl, i as normalizeWebsocketUrl, n as normalizeBaseUrl, o as resolveCohubEnvironment, r as normalizeVoiceInputWebsocketUrl, s as resolveVoiceInputWebsocketUrl, t as COHUB_ENVIRONMENTS } from "./chunks/environment.js";
|
|
4
4
|
import { a as extractBillingPayload, c as isFeatureNotEntitledError, i as FEATURE_NOT_ENTITLED_ERROR_CODE, l as isHttpErrorCode, n as createWebsocketClient, o as isBillingAccessBlockedCode, r as BILLING_ACCESS_BLOCKED_ERROR_CODE, s as isBillingAccessBlockedError, t as WebsocketClient } from "./chunks/websocket.js";
|
|
@@ -1934,6 +1934,7 @@ function createWorkBridgeCore(config) {
|
|
|
1934
1934
|
try {
|
|
1935
1935
|
if (data.type === "cohub.work.context") {
|
|
1936
1936
|
const workScopes = clonePermissionScopes(work.workScopes);
|
|
1937
|
+
const viewerUuid = await getViewerUuid();
|
|
1937
1938
|
reply(data.requestId, {
|
|
1938
1939
|
type: "cohub.work.context.result",
|
|
1939
1940
|
context: {
|
|
@@ -1943,6 +1944,8 @@ function createWorkBridgeCore(config) {
|
|
|
1943
1944
|
url: typeof location !== "undefined" ? location.href : ""
|
|
1944
1945
|
},
|
|
1945
1946
|
space: { id: work.spaceId },
|
|
1947
|
+
viewer: viewerUuid ? { userUuid: viewerUuid } : null,
|
|
1948
|
+
...config.invocation ? { invocation: { ...config.invocation } } : {},
|
|
1946
1949
|
permissions: {
|
|
1947
1950
|
scopes: workScopes,
|
|
1948
1951
|
workScopes,
|
|
@@ -2135,268 +2138,146 @@ function createWorkBridgeCore(config) {
|
|
|
2135
2138
|
}
|
|
2136
2139
|
//#endregion
|
|
2137
2140
|
//#region src/board/animation.ts
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
vertices: 0,
|
|
2141
|
-
dynamicVertices: 0,
|
|
2142
|
-
drawCalls: 0,
|
|
2143
|
-
filterPasses: 0,
|
|
2144
|
-
renderTexturePixels: 0,
|
|
2145
|
-
textureBytes: 0,
|
|
2146
|
-
bufferBytes: 0,
|
|
2147
|
-
simulationSteps: 0
|
|
2148
|
-
};
|
|
2149
|
-
const DEFAULT_BOARD_LIMITS = DEFAULT_BOARD_RENDER_LIMITS;
|
|
2150
|
-
const BUILTIN_CAPABILITIES = BOARD_BUILTIN_CAPABILITIES;
|
|
2151
|
-
function numericParam(params, key, fallback) {
|
|
2152
|
-
const value = params[key];
|
|
2153
|
-
return typeof value === "number" && Number.isFinite(value) ? value : fallback;
|
|
2141
|
+
function track(input) {
|
|
2142
|
+
return BoardTrackSchema.parse(input);
|
|
2154
2143
|
}
|
|
2155
|
-
function
|
|
2156
|
-
return {
|
|
2157
|
-
...
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
path: "params.bounds"
|
|
2174
|
-
});
|
|
2175
|
-
else {
|
|
2176
|
-
const value = bounds;
|
|
2177
|
-
if (![
|
|
2178
|
-
value.x,
|
|
2179
|
-
value.y,
|
|
2180
|
-
value.width,
|
|
2181
|
-
value.height
|
|
2182
|
-
].every((item) => typeof item === "number" && Number.isFinite(item)) || value.width <= 0 || value.height <= 0) diagnostics.push({
|
|
2183
|
-
severity: "error",
|
|
2184
|
-
code: "INVALID_PARTICLE_BOUNDS",
|
|
2185
|
-
message: "particle bounds must have a positive finite size",
|
|
2186
|
-
path: "params.bounds"
|
|
2187
|
-
});
|
|
2188
|
-
}
|
|
2189
|
-
}
|
|
2190
|
-
if (capability.id === "motion.path") {
|
|
2191
|
-
const points = params.points;
|
|
2192
|
-
if (!Array.isArray(points) || points.length < 2 || points.length > 1e4) diagnostics.push({
|
|
2193
|
-
severity: "error",
|
|
2194
|
-
code: "INVALID_MOTION_PATH",
|
|
2195
|
-
message: "motion path must contain 2 to 10000 points",
|
|
2196
|
-
path: "params.points"
|
|
2197
|
-
});
|
|
2198
|
-
}
|
|
2199
|
-
return diagnostics;
|
|
2144
|
+
function proceduralClip(input) {
|
|
2145
|
+
return BoardProceduralClipSchema.parse({
|
|
2146
|
+
...input,
|
|
2147
|
+
kindVersion: input.kindVersion ?? 1
|
|
2148
|
+
});
|
|
2149
|
+
}
|
|
2150
|
+
function composition(input) {
|
|
2151
|
+
return BoardCompositionSchema.parse(input);
|
|
2152
|
+
}
|
|
2153
|
+
function compileComposition(input) {
|
|
2154
|
+
return composition({
|
|
2155
|
+
id: input.id,
|
|
2156
|
+
name: input.name,
|
|
2157
|
+
timeline: {
|
|
2158
|
+
duration: input.duration,
|
|
2159
|
+
tracks: (input.tracks ?? []).map(track),
|
|
2160
|
+
clips: (input.clips ?? []).map(proceduralClip),
|
|
2161
|
+
markers: input.markers ?? []
|
|
2200
2162
|
},
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
return [
|
|
2206
|
-
value.x,
|
|
2207
|
-
value.y,
|
|
2208
|
-
value.width,
|
|
2209
|
-
value.height
|
|
2210
|
-
].every((item) => typeof item === "number" && Number.isFinite(item)) ? value : null;
|
|
2163
|
+
playback: input.playback ?? {
|
|
2164
|
+
loop: false,
|
|
2165
|
+
endBehavior: "hold",
|
|
2166
|
+
reducedMotion: { mode: "base" }
|
|
2211
2167
|
},
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
const particles = Math.max(0, Math.floor(numericParam(params, "count", 0)));
|
|
2216
|
-
return {
|
|
2217
|
-
particles,
|
|
2218
|
-
vertices: particles * 4,
|
|
2219
|
-
dynamicVertices: particles * 4,
|
|
2220
|
-
drawCalls: 1,
|
|
2221
|
-
bufferBytes: particles * 48,
|
|
2222
|
-
simulationSteps: particles
|
|
2223
|
-
};
|
|
2224
|
-
}
|
|
2225
|
-
case "effects.trail": return {
|
|
2226
|
-
vertices: 32,
|
|
2227
|
-
dynamicVertices: 32,
|
|
2228
|
-
drawCalls: 1,
|
|
2229
|
-
bufferBytes: 1024,
|
|
2230
|
-
simulationSteps: 16
|
|
2231
|
-
};
|
|
2232
|
-
case "effects.impact":
|
|
2233
|
-
case "effects.flash": return {
|
|
2234
|
-
vertices: 64,
|
|
2235
|
-
drawCalls: 1
|
|
2236
|
-
};
|
|
2237
|
-
case "effects.color": return {
|
|
2238
|
-
drawCalls: 1,
|
|
2239
|
-
filterPasses: 1
|
|
2240
|
-
};
|
|
2241
|
-
case "draw.reveal":
|
|
2242
|
-
case "draw.handwrite": return {
|
|
2243
|
-
drawCalls: 1,
|
|
2244
|
-
dynamicVertices: 1
|
|
2245
|
-
};
|
|
2246
|
-
default: return {};
|
|
2247
|
-
}
|
|
2248
|
-
}
|
|
2249
|
-
};
|
|
2168
|
+
metadata: input.metadata ?? {},
|
|
2169
|
+
revision: 0
|
|
2170
|
+
});
|
|
2250
2171
|
}
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2172
|
+
const clamp01 = (value) => Math.max(0, Math.min(1, value));
|
|
2173
|
+
function sampleEasing(easing, value) {
|
|
2174
|
+
const t = clamp01(value);
|
|
2175
|
+
switch (easing) {
|
|
2176
|
+
case "ease-in-quad": return t * t;
|
|
2177
|
+
case "ease-out-quad": return 1 - (1 - t) ** 2;
|
|
2178
|
+
case "ease-in-out-quad": return t < .5 ? 2 * t * t : 1 - (-2 * t + 2) ** 2 / 2;
|
|
2179
|
+
case "ease-in-cubic": return t ** 3;
|
|
2180
|
+
case "ease-out-cubic": return 1 - (1 - t) ** 3;
|
|
2181
|
+
case "ease-in-out-cubic": return t < .5 ? 4 * t ** 3 : 1 - (-2 * t + 2) ** 3 / 2;
|
|
2182
|
+
case "ease-out-quart": return 1 - (1 - t) ** 4;
|
|
2183
|
+
case "ease-out-expo": return t === 1 ? 1 : 1 - 2 ** (-10 * t);
|
|
2184
|
+
default: return t;
|
|
2256
2185
|
}
|
|
2257
|
-
return (hash >>> 0).toString(36).padStart(7, "0");
|
|
2258
|
-
}
|
|
2259
|
-
function stableId(prefix, seed, path) {
|
|
2260
|
-
return `${prefix}_${stableHash(`${seed}:${path}`)}`;
|
|
2261
|
-
}
|
|
2262
|
-
function assertDuration(value, field) {
|
|
2263
|
-
if (!Number.isFinite(value) || value < 0) throw new TypeError(`${field} must be a finite non-negative number`);
|
|
2264
2186
|
}
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
};
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
return {
|
|
2274
|
-
type: "parallel",
|
|
2275
|
-
children
|
|
2276
|
-
};
|
|
2277
|
-
},
|
|
2278
|
-
sequence(...children) {
|
|
2279
|
-
return {
|
|
2280
|
-
type: "sequence",
|
|
2281
|
-
children
|
|
2282
|
-
};
|
|
2283
|
-
},
|
|
2284
|
-
stagger(each, ...children) {
|
|
2285
|
-
assertDuration(each, "stagger each");
|
|
2286
|
-
return {
|
|
2287
|
-
type: "stagger",
|
|
2288
|
-
each,
|
|
2289
|
-
children
|
|
2290
|
-
};
|
|
2291
|
-
},
|
|
2292
|
-
delay(duration, child) {
|
|
2293
|
-
assertDuration(duration, "delay duration");
|
|
2294
|
-
return {
|
|
2295
|
-
type: "delay",
|
|
2296
|
-
duration,
|
|
2297
|
-
child
|
|
2298
|
-
};
|
|
2299
|
-
},
|
|
2300
|
-
repeat(count, child) {
|
|
2301
|
-
if (!Number.isSafeInteger(count) || count < 1 || count > 1e3) throw new TypeError("repeat count must be an integer between 1 and 1000");
|
|
2302
|
-
return {
|
|
2303
|
-
type: "repeat",
|
|
2304
|
-
count,
|
|
2305
|
-
child
|
|
2306
|
-
};
|
|
2187
|
+
function interpolate(left, right, progress) {
|
|
2188
|
+
if (typeof left === "number" && typeof right === "number") return left + (right - left) * progress;
|
|
2189
|
+
if (left && right && typeof left === "object" && typeof right === "object" && !Array.isArray(left) && !Array.isArray(right)) {
|
|
2190
|
+
const a = left;
|
|
2191
|
+
const b = right;
|
|
2192
|
+
const result = {};
|
|
2193
|
+
for (const key of /* @__PURE__ */ new Set([...Object.keys(a), ...Object.keys(b)])) result[key] = interpolate(a[key], b[key], progress);
|
|
2194
|
+
return result;
|
|
2307
2195
|
}
|
|
2308
|
-
|
|
2309
|
-
function clip(input) {
|
|
2310
|
-
assertDuration(input.duration, "clip duration");
|
|
2311
|
-
if (input.duration === 0) throw new TypeError("clip duration must be greater than zero");
|
|
2312
|
-
return timeline.clip({
|
|
2313
|
-
id: input.id,
|
|
2314
|
-
kind: input.kind,
|
|
2315
|
-
kindVersion: input.kindVersion ?? 1,
|
|
2316
|
-
target: input.target,
|
|
2317
|
-
duration: input.duration,
|
|
2318
|
-
layer: input.layer ?? "content",
|
|
2319
|
-
fill: input.fill ?? "none",
|
|
2320
|
-
easing: input.easing ?? "linear",
|
|
2321
|
-
params: input.params ?? {},
|
|
2322
|
-
keyframes: input.keyframes ?? [],
|
|
2323
|
-
assetRefs: input.assetRefs ?? [],
|
|
2324
|
-
seed: input.seed,
|
|
2325
|
-
metadata: input.metadata ?? {}
|
|
2326
|
-
});
|
|
2196
|
+
return progress < 1 ? left : right;
|
|
2327
2197
|
}
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
start: offset,
|
|
2337
|
-
seed: clipSeed
|
|
2338
|
-
}]
|
|
2339
|
-
};
|
|
2340
|
-
}
|
|
2341
|
-
if (input.type === "delay") {
|
|
2342
|
-
const nested = flatten(input.child, offset + input.duration, sequenceSeed, `${path}.child`);
|
|
2198
|
+
/** Deterministically sample one validated Track without touching scene state. */
|
|
2199
|
+
function sampleTrack(trackValue, time) {
|
|
2200
|
+
const frames = trackValue.keyframes;
|
|
2201
|
+
const first = frames[0];
|
|
2202
|
+
const last = frames.at(-1);
|
|
2203
|
+
if (!first || !last) return null;
|
|
2204
|
+
if (time < first.time) {
|
|
2205
|
+
if (trackValue.fill !== "backwards" && trackValue.fill !== "both") return null;
|
|
2343
2206
|
return {
|
|
2344
|
-
|
|
2345
|
-
|
|
2207
|
+
target: trackValue.target,
|
|
2208
|
+
channel: trackValue.channel,
|
|
2209
|
+
value: first.value
|
|
2346
2210
|
};
|
|
2347
2211
|
}
|
|
2348
|
-
if (
|
|
2349
|
-
|
|
2350
|
-
let cursor = offset;
|
|
2351
|
-
let total = 0;
|
|
2352
|
-
for (let index = 0; index < input.count; index += 1) {
|
|
2353
|
-
const nested = flatten(input.child, cursor, sequenceSeed, `${path}.${index}`);
|
|
2354
|
-
clips.push(...nested.clips);
|
|
2355
|
-
cursor += nested.duration;
|
|
2356
|
-
total += nested.duration;
|
|
2357
|
-
}
|
|
2212
|
+
if (time > last.time) {
|
|
2213
|
+
if (trackValue.fill !== "forwards" && trackValue.fill !== "both") return null;
|
|
2358
2214
|
return {
|
|
2359
|
-
|
|
2360
|
-
|
|
2215
|
+
target: trackValue.target,
|
|
2216
|
+
channel: trackValue.channel,
|
|
2217
|
+
value: last.value
|
|
2361
2218
|
};
|
|
2362
2219
|
}
|
|
2363
|
-
|
|
2364
|
-
let
|
|
2365
|
-
|
|
2366
|
-
const
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2220
|
+
let low = 0;
|
|
2221
|
+
let high = frames.length;
|
|
2222
|
+
while (low < high) {
|
|
2223
|
+
const middle = low + high >>> 1;
|
|
2224
|
+
if ((frames[middle]?.time ?? Number.POSITIVE_INFINITY) <= time) low = middle + 1;
|
|
2225
|
+
else high = middle;
|
|
2226
|
+
}
|
|
2227
|
+
const left = frames[Math.max(0, low - 1)] ?? first;
|
|
2228
|
+
const right = frames[Math.min(frames.length - 1, low)] ?? last;
|
|
2229
|
+
if (left === right || trackValue.interpolation === "step") return {
|
|
2230
|
+
target: trackValue.target,
|
|
2231
|
+
channel: trackValue.channel,
|
|
2232
|
+
value: left.value
|
|
2233
|
+
};
|
|
2234
|
+
const span = Math.max(Number.EPSILON, right.time - left.time);
|
|
2235
|
+
const progress = sampleEasing(right.easing ?? "linear", (time - left.time) / span);
|
|
2371
2236
|
return {
|
|
2372
|
-
|
|
2373
|
-
|
|
2237
|
+
target: trackValue.target,
|
|
2238
|
+
channel: trackValue.channel,
|
|
2239
|
+
value: interpolate(left.value, right.value, progress)
|
|
2374
2240
|
};
|
|
2375
2241
|
}
|
|
2376
|
-
function
|
|
2377
|
-
const
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2242
|
+
function sampleCompositionTracks(value, time) {
|
|
2243
|
+
const position = Math.max(0, Math.min(value.timeline.duration, time));
|
|
2244
|
+
return value.timeline.tracks.flatMap((item) => {
|
|
2245
|
+
const sampled = sampleTrack(item, position);
|
|
2246
|
+
return sampled ? [sampled] : [];
|
|
2247
|
+
});
|
|
2248
|
+
}
|
|
2249
|
+
const ZERO_COST = {
|
|
2250
|
+
particles: 0,
|
|
2251
|
+
vertices: 0,
|
|
2252
|
+
dynamicVertices: 0,
|
|
2253
|
+
drawCalls: 0,
|
|
2254
|
+
filterPasses: 0,
|
|
2255
|
+
renderTexturePixels: 0,
|
|
2256
|
+
textureBytes: 0,
|
|
2257
|
+
bufferBytes: 0,
|
|
2258
|
+
simulationSteps: 0
|
|
2259
|
+
};
|
|
2260
|
+
const DEFAULT_BOARD_LIMITS = DEFAULT_BOARD_RENDER_LIMITS;
|
|
2261
|
+
function builtinDefinition(capability) {
|
|
2381
2262
|
return {
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
duration: flattened.duration,
|
|
2386
|
-
seed: input.seed,
|
|
2387
|
-
restPose: input.restPose ?? {},
|
|
2388
|
-
metadata: input.metadata ?? {}
|
|
2263
|
+
...capability,
|
|
2264
|
+
validate() {
|
|
2265
|
+
return [];
|
|
2389
2266
|
},
|
|
2390
|
-
|
|
2391
|
-
|
|
2267
|
+
estimateCost(params) {
|
|
2268
|
+
return estimateBuiltinBoardClipCost({
|
|
2269
|
+
kind: capability.id,
|
|
2270
|
+
params
|
|
2271
|
+
});
|
|
2272
|
+
}
|
|
2392
2273
|
};
|
|
2393
2274
|
}
|
|
2394
|
-
function addCost(target, source) {
|
|
2395
|
-
for (const key of Object.keys(target)) target[key] += source[key] ?? 0;
|
|
2396
|
-
}
|
|
2397
2275
|
var BoardExtensionRegistry = class {
|
|
2398
2276
|
#extensions = /* @__PURE__ */ new Map();
|
|
2399
2277
|
#presets = /* @__PURE__ */ new Map();
|
|
2278
|
+
constructor() {
|
|
2279
|
+
for (const capability of BOARD_BUILTIN_CAPABILITIES) this.register(builtinDefinition(capability));
|
|
2280
|
+
}
|
|
2400
2281
|
register(definition) {
|
|
2401
2282
|
const key = `${definition.kind}:${definition.id}@${definition.version}`;
|
|
2402
2283
|
const target = definition.kind === "preset" ? this.#presets : this.#extensions;
|
|
@@ -2405,9 +2286,15 @@ var BoardExtensionRegistry = class {
|
|
|
2405
2286
|
return this;
|
|
2406
2287
|
}
|
|
2407
2288
|
capabilities() {
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2289
|
+
return [...this.#extensions.values(), ...this.#presets.values()].map((definition) => ({
|
|
2290
|
+
kind: definition.kind,
|
|
2291
|
+
id: definition.id,
|
|
2292
|
+
version: definition.version,
|
|
2293
|
+
...definition.digest ? { digest: definition.digest } : {},
|
|
2294
|
+
...definition.renderers ? { renderers: definition.renderers } : {},
|
|
2295
|
+
...definition.fallbackId ? { fallbackId: definition.fallbackId } : {},
|
|
2296
|
+
...definition.schema ? { schema: definition.schema } : {}
|
|
2297
|
+
}));
|
|
2411
2298
|
}
|
|
2412
2299
|
compilePreset(id, version, params) {
|
|
2413
2300
|
const preset = this.#presets.get(`preset:${id}@${version}`);
|
|
@@ -2415,74 +2302,72 @@ var BoardExtensionRegistry = class {
|
|
|
2415
2302
|
return preset.compile(params);
|
|
2416
2303
|
}
|
|
2417
2304
|
validate(input) {
|
|
2305
|
+
const parsed = BoardCompositionSchema.safeParse(input.composition);
|
|
2306
|
+
if (!parsed.success) return {
|
|
2307
|
+
valid: false,
|
|
2308
|
+
diagnostics: parsed.error.issues.map((issue) => ({
|
|
2309
|
+
severity: "error",
|
|
2310
|
+
code: "INVALID_COMPOSITION",
|
|
2311
|
+
message: issue.message,
|
|
2312
|
+
path: issue.path.join(".")
|
|
2313
|
+
})),
|
|
2314
|
+
peakCost: { ...ZERO_COST }
|
|
2315
|
+
};
|
|
2418
2316
|
const diagnostics = [];
|
|
2317
|
+
const composition = parsed.data;
|
|
2318
|
+
const cost = { ...ZERO_COST };
|
|
2419
2319
|
const events = [];
|
|
2420
|
-
const
|
|
2421
|
-
const persistentCost = { ...ZERO_COST };
|
|
2422
|
-
for (const [index, effect] of (input.effects ?? []).entries()) {
|
|
2423
|
-
const definition = this.#extensions.get(`effect:${effect.kind}@${effect.kindVersion}`);
|
|
2424
|
-
if (!definition) {
|
|
2425
|
-
diagnostics.push({
|
|
2426
|
-
severity: "warning",
|
|
2427
|
-
code: "UNKNOWN_EFFECT",
|
|
2428
|
-
message: `No renderer is registered for ${effect.kind}@${effect.kindVersion}`,
|
|
2429
|
-
path: `effects.${index}`
|
|
2430
|
-
});
|
|
2431
|
-
continue;
|
|
2432
|
-
}
|
|
2433
|
-
diagnostics.push(...definition.validate?.(effect.params) ?? []);
|
|
2434
|
-
addCost(persistentCost, definition.estimateCost(effect.params, profile));
|
|
2435
|
-
}
|
|
2436
|
-
for (const [index, clip] of input.clips.entries()) {
|
|
2320
|
+
for (const clip of composition.timeline.clips) {
|
|
2437
2321
|
const definition = this.#extensions.get(`clip:${clip.kind}@${clip.kindVersion}`);
|
|
2438
2322
|
if (!definition) {
|
|
2439
2323
|
diagnostics.push({
|
|
2440
2324
|
severity: "warning",
|
|
2441
2325
|
code: "UNKNOWN_CLIP",
|
|
2442
|
-
message: `No renderer is registered for ${clip.kind}@${clip.kindVersion}
|
|
2443
|
-
path: `clips.${index}`
|
|
2326
|
+
message: `No renderer is registered for ${clip.kind}@${clip.kindVersion}`
|
|
2444
2327
|
});
|
|
2445
2328
|
continue;
|
|
2446
2329
|
}
|
|
2330
|
+
diagnostics.push(...validateBuiltinBoardClip(clip, `composition.timeline.clips.${clip.id}`));
|
|
2447
2331
|
diagnostics.push(...definition.validate?.(clip.params) ?? []);
|
|
2448
|
-
const
|
|
2449
|
-
|
|
2332
|
+
const estimate = definition.estimateCost(clip.params, input.profile ?? "high");
|
|
2333
|
+
const clipCost = { ...ZERO_COST };
|
|
2334
|
+
for (const key of Object.keys(clipCost)) clipCost[key] = estimate[key] ?? 0;
|
|
2450
2335
|
events.push({
|
|
2451
2336
|
at: clip.start,
|
|
2452
2337
|
direction: 1,
|
|
2453
|
-
cost
|
|
2454
|
-
}
|
|
2338
|
+
cost: clipCost
|
|
2339
|
+
});
|
|
2340
|
+
events.push({
|
|
2455
2341
|
at: clip.start + clip.duration,
|
|
2456
2342
|
direction: -1,
|
|
2457
|
-
cost
|
|
2343
|
+
cost: clipCost
|
|
2458
2344
|
});
|
|
2459
2345
|
}
|
|
2460
2346
|
events.sort((left, right) => left.at - right.at || left.direction - right.direction);
|
|
2461
|
-
const
|
|
2462
|
-
const
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
peak[key] = Math.max(peak[key], current[key]);
|
|
2347
|
+
const active = { ...ZERO_COST };
|
|
2348
|
+
for (const event of events) for (const key of Object.keys(active)) {
|
|
2349
|
+
active[key] += event.cost[key] * event.direction;
|
|
2350
|
+
cost[key] = Math.max(cost[key], active[key]);
|
|
2466
2351
|
}
|
|
2352
|
+
for (const effect of input.effects ?? []) if (effect.kind === "effects.pulse" || effect.kind === "effects.float") cost.drawCalls += 1;
|
|
2467
2353
|
const limits = input.limits ?? DEFAULT_BOARD_LIMITS;
|
|
2468
|
-
for (const key of Object.keys(
|
|
2354
|
+
for (const key of Object.keys(cost)) if (cost[key] > limits[key]) diagnostics.push({
|
|
2469
2355
|
severity: "warning",
|
|
2470
2356
|
code: "RENDER_BUDGET_EXCEEDED",
|
|
2471
|
-
message: `${key} peaks at ${
|
|
2357
|
+
message: `${key} peaks at ${cost[key]}, above ${limits[key]}`,
|
|
2472
2358
|
path: key,
|
|
2473
2359
|
adaptation: { quality: "lower" }
|
|
2474
2360
|
});
|
|
2475
2361
|
return {
|
|
2476
2362
|
valid: !diagnostics.some((item) => item.severity === "error"),
|
|
2477
2363
|
diagnostics,
|
|
2478
|
-
peakCost:
|
|
2364
|
+
peakCost: cost
|
|
2479
2365
|
};
|
|
2480
2366
|
}
|
|
2481
2367
|
};
|
|
2482
|
-
function createBoardExtensionRegistry(
|
|
2483
|
-
|
|
2484
|
-
if (input.builtins !== false) for (const capability of BUILTIN_CAPABILITIES) registry.register(builtinDefinition(capability));
|
|
2485
|
-
return registry;
|
|
2368
|
+
function createBoardExtensionRegistry() {
|
|
2369
|
+
return new BoardExtensionRegistry();
|
|
2486
2370
|
}
|
|
2371
|
+
const BOARD_CHANNELS = BOARD_ANIMATION_CHANNELS;
|
|
2487
2372
|
//#endregion
|
|
2488
|
-
export { BILLING_ACCESS_BLOCKED_ERROR_CODE, BOARD_COLOR_IDS, BOARD_GEO_KINDS, BOARD_NATIVE_NODE_TYPES, BOARD_NODE_CONTRACT, BillingApi, BoardClient, BoardExtensionRegistry,
|
|
2373
|
+
export { BILLING_ACCESS_BLOCKED_ERROR_CODE, BOARD_ANIMATION_CHANNEL_CAPABILITIES, BOARD_CHANNELS, BOARD_COLOR_IDS, BOARD_GEO_KINDS, BOARD_NATIVE_NODE_TYPES, BOARD_NODE_CONTRACT, BillingApi, BoardAuthoringItemSchema, BoardClient, BoardCompositionInputSchema, BoardCompositionSchema, BoardEffectSchema, BoardExtensionRegistry, BoardItemPatchSchema, BoardPlaybackPolicySchema, BoardTransactionError, COHUB_ENVIRONMENTS, COHUB_SOURCE_HEADER, COHUB_SOURCE_HEADER_NAMES, CohubClient, CohubHttpClient, DEFAULT_BOARD_LIMITS, FEATURE_NOT_ENTITLED_ERROR_CODE, GenerationPolicyError, HttpError, ParentBridgeTransport, PopupBrokerTransport, REQUEST_SOURCE_VIA_MAX_LENGTH, ReferencesApi, ReferralsApi, SessionGenerationStreamClient, SessionPatchReducer, SpacePublicFilesApi, UI_COMMAND_DEFAULT_TIMEOUT_MS, UI_COMMAND_MAX_TIMEOUT_MS, UI_COMMAND_PAYLOAD_MAX_BYTES, UI_COMMAND_PENDING_TTL_SECONDS, UI_COMMAND_SETTLEMENT_GRACE_SECONDS, UI_COMMAND_TERMINAL_TTL_SECONDS, UI_COMMAND_VERSION, UiCommandsApi, UsersApi, VoiceApi, VoiceInputClient, WORK_COMPOSER_CHIP_CONTENT_MAX_BYTES, WORK_COMPOSER_CHIP_KEY_MAX_LENGTH, WORK_COMPOSER_CHIP_LABEL_MAX_LENGTH, WORK_SURFACE_READY_TIMEOUT_MS, WORK_SURFACE_REQUEST_TIMEOUT_MS, WebsocketClient, WorkCommerceApi, WorkRealtimeApi, WorkRefParseError, WorkRoom, WorkRuntimeApi, WorkSurfaceApi, WorksApi, assertGenerationRequestAllowedByPolicy, buildSpaceInvitePath, buildSpacePath, buildWorkSurfaceRequest, clearGrantedWorkScopes, compileComposition, composition, createBoardExtensionRegistry, createCohubClient, createHttpClient, createSessionGenerationStreamClient, createSessionPatchReducer, createSlugWorkIdResolver, createVoiceInputClient, createWebsocketClient, createWorkBridgeCore, createWorkRuntime, decodeGenerationPolicy, encodeGenerationPolicy, extractBillingPayload, filterDiscoverableGenerationModels, filterGenerationDeclarationsByPolicy, findGenerationModelPolicy, formatWorkRef, getAllowedGenerationModelIds, hasGrantedWorkScopes, hasRequestSourceIdentity, isBillingAccessBlockedCode, isBillingAccessBlockedError, isFeatureNotEntitledError, isGenerationModelHidden, isHttpErrorCode, isRequestSourceClientId, isRequestSourceEmpty, isRequestSourceUuid, isTerminalUiCommandStatus, isUiSurfaceMethod, isUuid, isWorkId, joinApiUrl, matchesUnauthorizedErrorToken, mergeRequestSourceIntoMeta, normalizeBaseUrl, normalizeGenerationPolicy, normalizeRequestSource, normalizeVoiceInputWebsocketUrl, normalizeWebsocketUrl, parseAssistantMessageCommit, parseBoardCompositionInput, parseBoardPlaybackPolicy, parseGenerationPolicyFromEnv, parseRequestSourceFromHeaders, parseUiCommand, parseWorkRef, parseWorkSurfaceReady, parseWorkSurfaceResponse, proceduralClip, readRequestSourceFromEnv, requestSourceToHeaders, resolveApiBaseUrl, resolveCohubEnvironment, resolveRequestSourceChannel, resolveVoiceInputWebsocketUrl, resolveWebsocketUrl, resolveWorkTransport, sampleCompositionTracks, sampleEasing, sampleTrack, sanitizeAccessToken, setGrantedWorkScopes, track, validateBoardNodeInput };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import { z } from "zod";
|