@crowdedkingdoms/crowdyjs 9.0.0 → 10.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.
Files changed (72) hide show
  1. package/MIGRATION.md +56 -34
  2. package/README.md +83 -50
  3. package/dist/crowdy-client.d.ts +3 -0
  4. package/dist/crowdy-client.d.ts.map +1 -1
  5. package/dist/crowdy-client.js +2 -0
  6. package/dist/domains/playerCodeProjects.d.ts +25 -0
  7. package/dist/domains/playerCodeProjects.d.ts.map +1 -0
  8. package/dist/domains/playerCodeProjects.js +299 -0
  9. package/dist/domains/playerCompute.d.ts +1 -1
  10. package/dist/domains/playerCompute.js +1 -1
  11. package/dist/generated/graphql.d.ts +792 -7
  12. package/dist/generated/graphql.d.ts.map +1 -1
  13. package/dist/generated/graphql.js +57 -0
  14. package/dist/index.d.ts +3 -5
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +3 -5
  17. package/dist/kit/npcs.d.ts.map +1 -1
  18. package/dist/kit/social.d.ts.map +1 -1
  19. package/dist/live-coding/rust-analysis.d.ts.map +1 -1
  20. package/dist/live-coding/rust-analysis.js +64 -1
  21. package/dist/live-coding/worker-transport.d.ts +3 -0
  22. package/dist/live-coding/worker-transport.d.ts.map +1 -1
  23. package/dist/live-coding/worker-transport.js +13 -0
  24. package/dist/mod-studio/controller.d.ts +188 -0
  25. package/dist/mod-studio/controller.d.ts.map +1 -0
  26. package/dist/mod-studio/controller.js +915 -0
  27. package/dist/mod-studio/diagnostics.d.ts +22 -0
  28. package/dist/mod-studio/diagnostics.d.ts.map +1 -0
  29. package/dist/mod-studio/diagnostics.js +141 -0
  30. package/dist/mod-studio/dom-shell.d.ts +55 -0
  31. package/dist/mod-studio/dom-shell.d.ts.map +1 -0
  32. package/dist/mod-studio/dom-shell.js +527 -0
  33. package/dist/mod-studio/editor.d.ts +17 -0
  34. package/dist/mod-studio/editor.d.ts.map +1 -0
  35. package/dist/mod-studio/editor.js +1 -0
  36. package/dist/mod-studio/index.d.ts +10 -0
  37. package/dist/mod-studio/index.d.ts.map +1 -0
  38. package/dist/mod-studio/index.js +9 -0
  39. package/dist/mod-studio/models.d.ts +149 -0
  40. package/dist/mod-studio/models.d.ts.map +1 -0
  41. package/dist/mod-studio/models.js +62 -0
  42. package/dist/mod-studio/monaco-editor.d.ts +16 -0
  43. package/dist/mod-studio/monaco-editor.d.ts.map +1 -0
  44. package/dist/mod-studio/monaco-editor.js +548 -0
  45. package/dist/mod-studio/mount.d.ts +17 -0
  46. package/dist/mod-studio/mount.d.ts.map +1 -0
  47. package/dist/mod-studio/mount.js +86 -0
  48. package/dist/mod-studio/starter-projects.d.ts +11 -0
  49. package/dist/mod-studio/starter-projects.d.ts.map +1 -0
  50. package/dist/mod-studio/starter-projects.js +102 -0
  51. package/dist/mod-studio/styles.d.ts +2 -0
  52. package/dist/mod-studio/styles.d.ts.map +1 -0
  53. package/dist/mod-studio/styles.js +14 -0
  54. package/dist/mod-studio/textarea-editor.d.ts +8 -0
  55. package/dist/mod-studio/textarea-editor.d.ts.map +1 -0
  56. package/dist/mod-studio/textarea-editor.js +71 -0
  57. package/package.json +4 -4
  58. package/dist/live-coding/ide.d.ts +0 -23
  59. package/dist/live-coding/ide.d.ts.map +0 -1
  60. package/dist/live-coding/ide.js +0 -514
  61. package/dist/live-coding/index.d.ts +0 -8
  62. package/dist/live-coding/index.d.ts.map +0 -1
  63. package/dist/live-coding/index.js +0 -7
  64. package/dist/live-coding/live-coding-controller.d.ts +0 -75
  65. package/dist/live-coding/live-coding-controller.d.ts.map +0 -1
  66. package/dist/live-coding/live-coding-controller.js +0 -141
  67. package/dist/live-coding/mount.d.ts +0 -26
  68. package/dist/live-coding/mount.d.ts.map +0 -1
  69. package/dist/live-coding/mount.js +0 -108
  70. package/dist/live-coding/templates.d.ts +0 -17
  71. package/dist/live-coding/templates.d.ts.map +0 -1
  72. package/dist/live-coding/templates.js +0 -59
@@ -0,0 +1,299 @@
1
+ import { CrowdyGraphQLError, CrowdyHttpError, CrowdyNetworkError, CrowdyTimeoutError, } from '../errors.js';
2
+ import { ModStudioOfflineError, ModStudioRevisionConflictError, normalizeModStudioPath, } from '../mod-studio/models.js';
3
+ import { PlayerCodeCommonFilesDocument, PlayerCodeImportSource, PlayerCodeLibraryFilesDocument, PlayerCodeLibrarySaveDocument, PlayerCodePairingPreference, PlayerCodeProjectCreateDocument, PlayerCodeProjectDocument, PlayerCodeProjectImportFileDocument, PlayerCodeProjectSaveDocument, PlayerCodeProjectsDocument, } from '../generated/graphql.js';
4
+ /**
5
+ * Typed Game API adapter for private Mod Studio projects and reusable files.
6
+ * Mutable projects remain separate from immutable player-compute versions;
7
+ * only the controller's deploy path converts target files to sourceFilesJson.
8
+ */
9
+ export class PlayerCodeProjectsAPI {
10
+ constructor(graphql) {
11
+ this.graphql = graphql;
12
+ this.baselines = new Map();
13
+ }
14
+ async listProjects(scope) {
15
+ const data = await this.request(PlayerCodeProjectsDocument, {
16
+ appId: scope.appId,
17
+ includeArchived: false,
18
+ limit: 50,
19
+ offset: 0,
20
+ });
21
+ return data.playerCodeProjects.map(fromSummaryDto);
22
+ }
23
+ async getProject(input) {
24
+ const data = await this.request(PlayerCodeProjectDocument, {
25
+ appId: input.appId,
26
+ projectId: input.projectId,
27
+ });
28
+ return this.remember(fromProjectDto(data.playerCodeProject, input.gridId));
29
+ }
30
+ async createProject(input) {
31
+ const data = await this.request(PlayerCodeProjectCreateDocument, {
32
+ input: {
33
+ appId: input.appId,
34
+ gridId: input.gridId,
35
+ name: input.metadata.name,
36
+ description: input.metadata.description ?? null,
37
+ serverModuleName: input.metadata.serverModuleName ?? null,
38
+ clientModuleName: input.metadata.clientModuleName ?? null,
39
+ pairingPreference: toApiPairing(input.kind, input.metadata.pairingPreference),
40
+ sdkVersion: '0.1.5',
41
+ abiVersion: 0,
42
+ initialFiles: input.files.map(toApiFile),
43
+ },
44
+ });
45
+ return this.remember(fromProjectDto(data.playerCodeProjectCreate, input.gridId));
46
+ }
47
+ async saveProject(input) {
48
+ try {
49
+ const baseline = this.baselines.get(input.projectId) ??
50
+ (await this.getProject({
51
+ appId: input.appId,
52
+ gridId: input.gridId,
53
+ projectId: input.projectId,
54
+ }));
55
+ const delta = projectFileDelta(baseline, input);
56
+ const data = await this.request(PlayerCodeProjectSaveDocument, {
57
+ input: {
58
+ appId: input.appId,
59
+ projectId: input.projectId,
60
+ expectedRevision: input.expectedRevisionId,
61
+ gridId: input.gridId,
62
+ name: input.metadata.name,
63
+ description: input.metadata.description ?? null,
64
+ serverModuleName: input.metadata.serverModuleName ?? null,
65
+ clientModuleName: input.metadata.clientModuleName ?? null,
66
+ pairingPreference: toApiPairing(projectKind(input), input.metadata.pairingPreference),
67
+ upserts: delta.upserts.map(toApiFile),
68
+ deletes: delta.deletes.map(({ target, path }) => ({
69
+ target: target,
70
+ path,
71
+ })),
72
+ },
73
+ });
74
+ return this.remember(fromProjectDto(data.playerCodeProjectSave, input.gridId));
75
+ }
76
+ catch (error) {
77
+ if (error instanceof CrowdyGraphQLError &&
78
+ error.code === 'CONFLICT' &&
79
+ error.message.includes('PLAYER_CODE_REVISION_CONFLICT')) {
80
+ let remoteProject;
81
+ try {
82
+ remoteProject = await this.getProject({
83
+ appId: input.appId,
84
+ gridId: input.gridId,
85
+ projectId: input.projectId,
86
+ });
87
+ }
88
+ catch {
89
+ // The conflict remains actionable if the follow-up read fails.
90
+ }
91
+ throw new ModStudioRevisionConflictError(error.message, remoteProject);
92
+ }
93
+ throw error;
94
+ }
95
+ }
96
+ async listPersonalLibraryFiles(scope) {
97
+ const data = await this.request(PlayerCodeLibraryFilesDocument, {
98
+ appId: scope.appId,
99
+ includeArchived: false,
100
+ limit: 100,
101
+ offset: 0,
102
+ });
103
+ return data.playerCodeLibraryFiles.map(fromLibraryDto);
104
+ }
105
+ async savePersonalLibraryFile(input) {
106
+ const data = await this.request(PlayerCodeLibrarySaveDocument, {
107
+ input: {
108
+ appId: input.appId,
109
+ title: input.title,
110
+ pathHint: normalizeModStudioPath(input.path),
111
+ target: input.target,
112
+ tags: input.tags ?? [],
113
+ content: input.content,
114
+ },
115
+ });
116
+ return fromLibraryDto(data.playerCodeLibrarySave);
117
+ }
118
+ async listCommonFiles(scope) {
119
+ const data = await this.request(PlayerCodeCommonFilesDocument, {
120
+ appId: scope.appId,
121
+ limit: 100,
122
+ offset: 0,
123
+ });
124
+ return data.playerCodeCommonFiles.map(fromCommonDto);
125
+ }
126
+ async importReferenceFile(input) {
127
+ const data = await this.request(PlayerCodeProjectImportFileDocument, {
128
+ input: {
129
+ appId: input.appId,
130
+ projectId: input.projectId,
131
+ expectedProjectRevision: input.expectedRevisionId,
132
+ source: input.source === 'PERSONAL_LIBRARY'
133
+ ? PlayerCodeImportSource.Library
134
+ : PlayerCodeImportSource.Common,
135
+ ...(input.source === 'PERSONAL_LIBRARY'
136
+ ? { libraryFileId: input.referenceId }
137
+ : { commonVersionId: input.referenceId }),
138
+ ...(input.destinationPath
139
+ ? { destinationPath: normalizeModStudioPath(input.destinationPath) }
140
+ : {}),
141
+ },
142
+ });
143
+ return this.remember(fromProjectDto(data.playerCodeProjectImportFile, input.gridId));
144
+ }
145
+ remember(project) {
146
+ this.baselines.set(project.projectId, cloneProject(project));
147
+ return project;
148
+ }
149
+ async request(document, variables) {
150
+ try {
151
+ return await this.graphql.request(document, variables);
152
+ }
153
+ catch (error) {
154
+ if (error instanceof CrowdyNetworkError ||
155
+ error instanceof CrowdyTimeoutError ||
156
+ (error instanceof CrowdyHttpError && error.status >= 500)) {
157
+ throw new ModStudioOfflineError(error.message, error);
158
+ }
159
+ throw error;
160
+ }
161
+ }
162
+ }
163
+ function fromSummaryDto(dto) {
164
+ return {
165
+ projectId: dto.projectId,
166
+ name: dto.name,
167
+ kind: kindFromApi(dto.pairingPreference),
168
+ revisionId: String(dto.revision),
169
+ ...(dto.serverModuleName
170
+ ? { serverModuleName: dto.serverModuleName }
171
+ : {}),
172
+ ...(dto.clientModuleName
173
+ ? { clientModuleName: dto.clientModuleName }
174
+ : {}),
175
+ updatedAt: dto.updatedAt,
176
+ };
177
+ }
178
+ function fromProjectDto(dto, fallbackGridId) {
179
+ const files = dto.files.map((file) => ({
180
+ target: file.target,
181
+ path: normalizeModStudioPath(file.path),
182
+ content: file.content,
183
+ }));
184
+ return {
185
+ projectId: dto.projectId,
186
+ appId: String(dto.appId),
187
+ gridId: dto.gridId == null ? fallbackGridId : String(dto.gridId),
188
+ kind: kindFromApi(dto.pairingPreference),
189
+ metadata: {
190
+ name: dto.name,
191
+ ...(dto.description ? { description: dto.description } : {}),
192
+ ...(dto.serverModuleName
193
+ ? { serverModuleName: dto.serverModuleName }
194
+ : {}),
195
+ ...(dto.clientModuleName
196
+ ? { clientModuleName: dto.clientModuleName }
197
+ : {}),
198
+ pairingPreference: fromApiPairing(dto.pairingPreference),
199
+ },
200
+ files,
201
+ sdkVersion: dto.sdkVersion,
202
+ abiVersion: dto.abiVersion,
203
+ revision: {
204
+ id: String(dto.revision),
205
+ savedAt: dto.updatedAt,
206
+ },
207
+ createdAt: dto.createdAt,
208
+ updatedAt: dto.updatedAt,
209
+ };
210
+ }
211
+ function fromLibraryDto(dto) {
212
+ return {
213
+ id: dto.libraryFileId,
214
+ source: 'PERSONAL_LIBRARY',
215
+ title: dto.title,
216
+ target: dto.target,
217
+ path: normalizeModStudioPath(dto.pathHint),
218
+ content: dto.content,
219
+ tags: [...dto.tags],
220
+ updatedAt: dto.updatedAt,
221
+ };
222
+ }
223
+ function fromCommonDto(dto) {
224
+ return {
225
+ id: dto.versionId,
226
+ source: 'COMMON',
227
+ title: dto.title,
228
+ target: dto.target,
229
+ path: normalizeModStudioPath(dto.path),
230
+ content: dto.content,
231
+ tags: [...dto.tags],
232
+ updatedAt: dto.updatedAt,
233
+ };
234
+ }
235
+ function kindFromApi(pairing) {
236
+ if (pairing === PlayerCodePairingPreference.ServerOnly)
237
+ return 'SERVER';
238
+ if (pairing === PlayerCodePairingPreference.ClientOnly)
239
+ return 'CLIENT';
240
+ return 'FULL_STACK';
241
+ }
242
+ function fromApiPairing(pairing) {
243
+ if (pairing === PlayerCodePairingPreference.Paired)
244
+ return 'REQUIRED';
245
+ if (pairing === PlayerCodePairingPreference.Independent)
246
+ return 'OPTIONAL';
247
+ return 'NONE';
248
+ }
249
+ function toApiPairing(kind, pairing) {
250
+ if (kind === 'SERVER')
251
+ return PlayerCodePairingPreference.ServerOnly;
252
+ if (kind === 'CLIENT')
253
+ return PlayerCodePairingPreference.ClientOnly;
254
+ return pairing === 'REQUIRED'
255
+ ? PlayerCodePairingPreference.Paired
256
+ : PlayerCodePairingPreference.Independent;
257
+ }
258
+ function toApiFile(file) {
259
+ return {
260
+ target: file.target,
261
+ path: normalizeModStudioPath(file.path),
262
+ content: file.content,
263
+ };
264
+ }
265
+ function projectKind(input) {
266
+ const hasServer = input.files.some((file) => file.target === 'SERVER');
267
+ const hasClient = input.files.some((file) => file.target === 'CLIENT');
268
+ if (hasServer && hasClient)
269
+ return 'FULL_STACK';
270
+ if (hasServer)
271
+ return 'SERVER';
272
+ return 'CLIENT';
273
+ }
274
+ function projectFileDelta(baseline, input) {
275
+ const previous = new Map(baseline.files.map((file) => [
276
+ `${file.target}:${normalizeModStudioPath(file.path)}`,
277
+ file,
278
+ ]));
279
+ const current = new Map(input.files.map((file) => [
280
+ `${file.target}:${normalizeModStudioPath(file.path)}`,
281
+ file,
282
+ ]));
283
+ const upserts = input.files.filter((file) => {
284
+ const before = previous.get(`${file.target}:${normalizeModStudioPath(file.path)}`);
285
+ return !before || before.content !== file.content;
286
+ });
287
+ const deletes = baseline.files
288
+ .filter((file) => !current.has(`${file.target}:${normalizeModStudioPath(file.path)}`))
289
+ .map((file) => ({ target: file.target, path: file.path }));
290
+ return { upserts, deletes };
291
+ }
292
+ function cloneProject(project) {
293
+ return {
294
+ ...project,
295
+ metadata: { ...project.metadata },
296
+ files: project.files.map((file) => ({ ...file })),
297
+ revision: { ...project.revision },
298
+ };
299
+ }
@@ -77,7 +77,7 @@ export declare class PlayerComputeAPI {
77
77
  /**
78
78
  * Fetch a client artifact and decode its bytes to an ArrayBuffer plus the
79
79
  * broker inputs (content hash for side-load verification, per-dispatch fuel
80
- * budget). Convenience over {@link artifact} for the live-coding client
80
+ * budget). Convenience over {@link artifact} for the Mod Studio CLIENT
81
81
  * deploy loop.
82
82
  */
83
83
  artifactBytes(variables: PlayerComputeArtifactQueryVariables): Promise<{
@@ -116,7 +116,7 @@ export class PlayerComputeAPI {
116
116
  /**
117
117
  * Fetch a client artifact and decode its bytes to an ArrayBuffer plus the
118
118
  * broker inputs (content hash for side-load verification, per-dispatch fuel
119
- * budget). Convenience over {@link artifact} for the live-coding client
119
+ * budget). Convenience over {@link artifact} for the Mod Studio CLIENT
120
120
  * deploy loop.
121
121
  */
122
122
  async artifactBytes(variables) {