@cueframe/studio-convex 0.1.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/dist/index.js ADDED
@@ -0,0 +1,298 @@
1
+ // src/errors.ts
2
+ import { StudioError, StudioErrorEnvelope } from "@cueframe/studio-contracts";
3
+ function studioErrorFromConvex(error) {
4
+ if (error === null || typeof error !== "object" || !("data" in error)) return null;
5
+ const data = error.data;
6
+ const direct = StudioError.safeParse(data);
7
+ if (direct.success) return direct.data;
8
+ const envelope = StudioErrorEnvelope.safeParse(data);
9
+ return envelope.success ? envelope.data.error : null;
10
+ }
11
+ var StudioRemoteError = class extends Error {
12
+ constructor(studioError, options) {
13
+ super(studioError.message, options);
14
+ this.studioError = studioError;
15
+ this.name = "StudioRemoteError";
16
+ this.code = studioError.code;
17
+ this.retryable = studioError.retryable;
18
+ this.details = studioError.details;
19
+ }
20
+ studioError;
21
+ code;
22
+ retryable;
23
+ details;
24
+ };
25
+ function normalizeStudioConvexError(error) {
26
+ const studioError = studioErrorFromConvex(error);
27
+ return studioError === null ? error : new StudioRemoteError(studioError, { cause: error });
28
+ }
29
+
30
+ // src/bindings.ts
31
+ import { makeFunctionReference } from "convex/server";
32
+ import {
33
+ STUDIO_OPERATIONS
34
+ } from "@cueframe/studio-contracts";
35
+ var STUDIO_FUNCTION_PATHS = {
36
+ compatibility: "studio/v1/compatibility:get",
37
+ sessionCurrent: "studio/v1/session:current",
38
+ assistantResolveThread: "studio/v1/assistant:resolveThread",
39
+ assistantForgetConversation: "studio/v1/assistant:forgetConversation",
40
+ assistantSend: "studio/v1/assistant:send",
41
+ assistantMessages: "studio/v1/assistant:messages",
42
+ projectsList: "studio/v1/projects:list",
43
+ projectsSnapshot: "studio/v1/projects:snapshot",
44
+ projectsCreate: "studio/v1/projects:create",
45
+ projectsUpdate: "studio/v1/projects:update",
46
+ projectsRemove: "studio/v1/projects:remove",
47
+ compositionsApply: "studio/v1/compositions:apply",
48
+ compositionsReplace: "studio/v1/compositions:replace",
49
+ mediaList: "studio/v1/media:list",
50
+ mediaRemove: "studio/v1/media:remove",
51
+ mediaCancelProcessing: "studio/v1/media:cancelProcessing",
52
+ mediaReprocess: "studio/v1/media:reprocess",
53
+ mediaListUnderstanding: "studio/v1/media:listUnderstanding",
54
+ mediaSearch: "studio/v1/media:search",
55
+ mediaAnalyzeTimeline: "studio/v1/media:analyzeTimeline",
56
+ mediaFacts: "studio/v1/media:facts",
57
+ mediaPurchaseFact: "studio/v1/media:purchaseFact",
58
+ transcriptsList: "studio/v1/transcripts:list",
59
+ transcriptsGetDownload: "studio/v1/transcripts:getDownload",
60
+ transcriptsSearch: "studio/v1/transcripts:search",
61
+ correctionsList: "studio/v1/corrections:list",
62
+ correctionsSave: "studio/v1/corrections:save",
63
+ correctionsRemove: "studio/v1/corrections:remove",
64
+ settingsGetUser: "studio/v1/settings:getUser",
65
+ settingsUpdateProcessing: "studio/v1/settings:updateProcessing",
66
+ brandKitsList: "studio/v1/brandKits:list",
67
+ brandKitsUpsert: "studio/v1/brandKits:upsert",
68
+ componentsList: "studio/v1/components:list",
69
+ componentsGetBundles: "studio/v1/components:getBundles",
70
+ conversationsList: "studio/v1/conversations:list",
71
+ conversationsGet: "studio/v1/conversations:get",
72
+ conversationsSave: "studio/v1/conversations:save",
73
+ conversationsAdopt: "studio/v1/conversations:adopt",
74
+ conversationsRemove: "studio/v1/conversations:remove",
75
+ restorePointsList: "studio/v1/restorePoints:listForConversation",
76
+ restorePointsForget: "studio/v1/restorePoints:forgetForConversation",
77
+ restorePointsRestore: "studio/v1/restorePoints:restore",
78
+ rendersList: "studio/v1/renders:list",
79
+ rendersPresignOutput: "studio/v1/renders:presignOutput",
80
+ rendersCreate: "studio/v1/renders:create",
81
+ rendersCancel: "studio/v1/renders:cancel",
82
+ uploadsBegin: "studio/v1/uploads:begin",
83
+ uploadsFinalize: "studio/v1/uploads:finalize",
84
+ templatesList: "studio/v1/templates:list",
85
+ templatesGet: "studio/v1/templates:get",
86
+ templatesSave: "studio/v1/templates:save",
87
+ templatesRemove: "studio/v1/templates:remove",
88
+ projectResourcesBeginUpload: "studio/v1/projectResources:beginUpload",
89
+ projectResourcesFinalizeUpload: "studio/v1/projectResources:finalizeUpload",
90
+ projectResourcesRemove: "studio/v1/projectResources:remove",
91
+ projectResourcesGetDelivery: "studio/v1/projectResources:getDelivery",
92
+ resourcesSearch: "studio/v1/resources:search",
93
+ importsResolveDropbox: "studio/v1/imports:resolveDropbox",
94
+ importsDropboxFile: "studio/v1/imports:dropboxFile"
95
+ };
96
+ function bind(id) {
97
+ const definition = STUDIO_OPERATIONS[id];
98
+ const path = STUDIO_FUNCTION_PATHS[id];
99
+ const paginated = "paginated" in definition && definition.paginated === true;
100
+ const parseInput = (value) => definition.input.parse(value);
101
+ const parseResult = (value) => {
102
+ if (!paginated) return definition.result.parse(value);
103
+ const native = value;
104
+ return definition.result.parse({
105
+ items: native?.page,
106
+ nextCursor: native?.isDone ? null : native?.continueCursor,
107
+ done: native?.isDone
108
+ });
109
+ };
110
+ return {
111
+ id,
112
+ path,
113
+ kind: definition.kind,
114
+ durable: definition.durable,
115
+ aggregate: definition.aggregate,
116
+ revisionPolicy: definition.revisionPolicy,
117
+ paginated,
118
+ reference: makeFunctionReference(path),
119
+ parseInput,
120
+ encodeInput: (value) => {
121
+ const parsed = parseInput(value);
122
+ if (!paginated) return parsed;
123
+ const page = parsed;
124
+ const { cursor, limit, ...filters } = page;
125
+ return {
126
+ ...filters,
127
+ paginationOpts: { numItems: limit, cursor: cursor ?? null }
128
+ };
129
+ },
130
+ parseResult,
131
+ parsePageItems: (value) => {
132
+ if (!paginated) throw new TypeError(`${id} is not paginated`);
133
+ const parsed = definition.result.parse({ items: value, nextCursor: null, done: true });
134
+ return parsed.items;
135
+ }
136
+ };
137
+ }
138
+ var studioFunctions = Object.fromEntries(
139
+ Object.keys(STUDIO_OPERATIONS).map((id) => [id, bind(id)])
140
+ );
141
+
142
+ // src/compatibility.ts
143
+ import { STUDIO_CONTRACT_VERSION } from "@cueframe/studio-contracts";
144
+ var STUDIO_CLIENT_VERSION = `studio/${import.meta.env?.VITE_APP_VERSION ?? "dev"}`;
145
+ var StudioCompatibilityError = class extends Error {
146
+ constructor(minimumClientVersion) {
147
+ super(`This CueFrame build is no longer compatible with the hosted Studio service. Upgrade to ${minimumClientVersion} or later.`);
148
+ this.minimumClientVersion = minimumClientVersion;
149
+ this.name = "StudioCompatibilityError";
150
+ }
151
+ minimumClientVersion;
152
+ };
153
+ var compatibilityChecks = /* @__PURE__ */ new WeakMap();
154
+ function ensureStudioCompatibility(client, clientVersion = STUDIO_CLIENT_VERSION) {
155
+ let byVersion = compatibilityChecks.get(client);
156
+ if (!byVersion) {
157
+ byVersion = /* @__PURE__ */ new Map();
158
+ compatibilityChecks.set(client, byVersion);
159
+ }
160
+ const cacheKey = `${STUDIO_CONTRACT_VERSION}:${clientVersion}`;
161
+ const existing = byVersion.get(cacheKey);
162
+ if (existing) return existing;
163
+ const check = (async () => {
164
+ const binding = studioFunctions.compatibility;
165
+ const input = binding.parseInput({
166
+ clientVersion,
167
+ contractVersion: STUDIO_CONTRACT_VERSION
168
+ });
169
+ let wire;
170
+ try {
171
+ wire = await client.query(binding.reference, input);
172
+ } catch (error) {
173
+ throw normalizeStudioConvexError(error);
174
+ }
175
+ const result = binding.parseResult(wire);
176
+ if (!result.compatible) throw new StudioCompatibilityError(result.minimumClientVersion);
177
+ })();
178
+ const cached = check.catch((error) => {
179
+ if (!(error instanceof StudioCompatibilityError)) byVersion?.delete(cacheKey);
180
+ throw error;
181
+ });
182
+ byVersion.set(cacheKey, cached);
183
+ return cached;
184
+ }
185
+
186
+ // src/pagination.ts
187
+ import { usePaginatedQuery } from "convex/react";
188
+ function useStudioPaginatedQuery(id, args, options) {
189
+ const binding = studioFunctions[id];
190
+ if (!binding.paginated) throw new TypeError(`${id} is not a paginated Studio operation`);
191
+ const filters = args === "skip" ? "skip" : (() => {
192
+ const encoded = binding.encodeInput({ ...args, limit: options.initialNumItems });
193
+ const { paginationOpts: _paginationOpts, ...validated } = encoded;
194
+ return validated;
195
+ })();
196
+ const page = usePaginatedQuery(
197
+ binding.reference,
198
+ filters,
199
+ options
200
+ );
201
+ return {
202
+ ...page,
203
+ results: binding.parsePageItems(page.results)
204
+ };
205
+ }
206
+
207
+ // src/abi.ts
208
+ import { STUDIO_OPERATIONS as STUDIO_OPERATIONS2 } from "@cueframe/studio-contracts";
209
+ var STUDIO_CONVEX_ARTIFACT = Object.freeze({
210
+ name: "@cueframe/studio-convex",
211
+ version: "0.1.0",
212
+ integritySha256: "sha256:e980ed768236d9498c46d7f294537644a395e236e02269d9ef2e1d18cc97a2c7"
213
+ });
214
+ var STUDIO_CONVEX_ABI = Object.freeze({
215
+ artifact: STUDIO_CONVEX_ARTIFACT,
216
+ operations: Object.freeze(Object.fromEntries(
217
+ Object.keys(STUDIO_OPERATIONS2).map((id) => {
218
+ const operation = STUDIO_OPERATIONS2[id];
219
+ return [id, Object.freeze({
220
+ path: STUDIO_FUNCTION_PATHS[id],
221
+ kind: operation.kind,
222
+ durable: operation.durable,
223
+ aggregate: operation.aggregate,
224
+ revisionPolicy: operation.revisionPolicy,
225
+ paginated: "paginated" in operation && operation.paginated === true
226
+ })];
227
+ })
228
+ ))
229
+ });
230
+
231
+ // src/index.ts
232
+ var compatibilityRef = studioFunctions.compatibility.reference;
233
+ var sessionRef = studioFunctions.sessionCurrent.reference;
234
+ var projectListRef = studioFunctions.projectsList.reference;
235
+ var projectSnapshotRef = studioFunctions.projectsSnapshot.reference;
236
+ var createProjectRef = studioFunctions.projectsCreate.reference;
237
+ var updateProjectRef = studioFunctions.projectsUpdate.reference;
238
+ var removeProjectRef = studioFunctions.projectsRemove.reference;
239
+ var applyCompositionRef = studioFunctions.compositionsApply.reference;
240
+ var replaceCompositionRef = studioFunctions.compositionsReplace.reference;
241
+ var parseCompatibilityInput = studioFunctions.compatibility.parseInput;
242
+ var parseCompatibilityResult = studioFunctions.compatibility.parseResult;
243
+ var parseSessionInput = studioFunctions.sessionCurrent.parseInput;
244
+ var parseSessionResult = studioFunctions.sessionCurrent.parseResult;
245
+ var parseProjectListInput = studioFunctions.projectsList.parseInput;
246
+ var parseProjectListResult = studioFunctions.projectsList.parseResult;
247
+ var parseProjectSnapshotInput = studioFunctions.projectsSnapshot.parseInput;
248
+ var parseProjectSnapshotResult = studioFunctions.projectsSnapshot.parseResult;
249
+ var parseCreateProjectInput = studioFunctions.projectsCreate.parseInput;
250
+ var parseCreateProjectResult = studioFunctions.projectsCreate.parseResult;
251
+ var parseUpdateProjectInput = studioFunctions.projectsUpdate.parseInput;
252
+ var parseUpdateProjectResult = studioFunctions.projectsUpdate.parseResult;
253
+ var parseRemoveProjectInput = studioFunctions.projectsRemove.parseInput;
254
+ var parseRemoveProjectResult = studioFunctions.projectsRemove.parseResult;
255
+ var parseApplyCompositionInput = studioFunctions.compositionsApply.parseInput;
256
+ var parseApplyCompositionResult = studioFunctions.compositionsApply.parseResult;
257
+ var parseReplaceCompositionInput = studioFunctions.compositionsReplace.parseInput;
258
+ var parseReplaceCompositionResult = studioFunctions.compositionsReplace.parseResult;
259
+ export {
260
+ STUDIO_CLIENT_VERSION,
261
+ STUDIO_CONVEX_ABI,
262
+ STUDIO_CONVEX_ARTIFACT,
263
+ STUDIO_FUNCTION_PATHS,
264
+ StudioCompatibilityError,
265
+ StudioRemoteError,
266
+ applyCompositionRef,
267
+ compatibilityRef,
268
+ createProjectRef,
269
+ ensureStudioCompatibility,
270
+ normalizeStudioConvexError,
271
+ parseApplyCompositionInput,
272
+ parseApplyCompositionResult,
273
+ parseCompatibilityInput,
274
+ parseCompatibilityResult,
275
+ parseCreateProjectInput,
276
+ parseCreateProjectResult,
277
+ parseProjectListInput,
278
+ parseProjectListResult,
279
+ parseProjectSnapshotInput,
280
+ parseProjectSnapshotResult,
281
+ parseRemoveProjectInput,
282
+ parseRemoveProjectResult,
283
+ parseReplaceCompositionInput,
284
+ parseReplaceCompositionResult,
285
+ parseSessionInput,
286
+ parseSessionResult,
287
+ parseUpdateProjectInput,
288
+ parseUpdateProjectResult,
289
+ projectListRef,
290
+ projectSnapshotRef,
291
+ removeProjectRef,
292
+ replaceCompositionRef,
293
+ sessionRef,
294
+ studioErrorFromConvex,
295
+ studioFunctions,
296
+ updateProjectRef,
297
+ useStudioPaginatedQuery
298
+ };
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "@cueframe/studio-convex",
3
+ "version": "0.1.0",
4
+ "description": "Explicit Convex function references and runtime parsers for hosted CueFrame Studio.",
5
+ "type": "module",
6
+ "license": "AGPL-3.0-only",
7
+ "main": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js"
13
+ }
14
+ },
15
+ "dependencies": {
16
+ "@cueframe/studio-contracts": "^0.1.0"
17
+ },
18
+ "peerDependencies": {
19
+ "convex": ">=1.42",
20
+ "react": ">=18"
21
+ },
22
+ "devDependencies": {
23
+ "convex": "^1.42.3",
24
+ "react": "^19.2.7",
25
+ "tsup": "^8.3.5",
26
+ "typescript": "^5.9.3",
27
+ "vitest": "^4.1.2"
28
+ },
29
+ "files": [
30
+ "dist",
31
+ "README.md"
32
+ ],
33
+ "publishConfig": {
34
+ "access": "public"
35
+ },
36
+ "repository": {
37
+ "type": "git",
38
+ "url": "git+https://github.com/cueframe-ai/cueframe.git",
39
+ "directory": "packages/studio-convex"
40
+ },
41
+ "engines": {
42
+ "node": ">=24"
43
+ },
44
+ "scripts": {
45
+ "build": "tsup src/index.ts --format esm --dts --clean --out-dir dist",
46
+ "check": "tsc --noEmit",
47
+ "test": "vitest run"
48
+ }
49
+ }