@noya-app/noya-multiplayer-react 0.1.71 → 0.1.73

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/package.json CHANGED
@@ -1,10 +1,9 @@
1
1
  {
2
2
  "name": "@noya-app/noya-multiplayer-react",
3
- "version": "0.1.71",
3
+ "version": "0.1.73",
4
4
  "main": "./dist/index.js",
5
5
  "module": "./dist/index.mjs",
6
6
  "types": "./dist/index.d.ts",
7
- "browser": "./dist/index.bundle.js",
8
7
  "scripts": {
9
8
  "build": "npm run build:bundle && npm run build:main",
10
9
  "build:main": "tsup src/index.ts --format cjs,esm --dts --sourcemap",
@@ -12,7 +11,7 @@
12
11
  "dev": "npm run build -- --watch"
13
12
  },
14
13
  "dependencies": {
15
- "@noya-app/state-manager": "0.1.57",
14
+ "@noya-app/state-manager": "0.1.58",
16
15
  "@noya-app/emitter": "0.1.0",
17
16
  "@noya-app/observable": "0.1.12",
18
17
  "@noya-app/task-runner": "0.1.6",
@@ -3,6 +3,7 @@
3
3
  import { MenuItem } from "@noya-app/noya-designsystem";
4
4
  import {
5
5
  CreateResourceParametersWithoutAccessibleByFileId,
6
+ DeleteResourceParameters,
6
7
  diffResourceMaps,
7
8
  Input,
8
9
  MediaItem,
@@ -22,17 +23,20 @@ import {
22
23
  import { useJsonMemo, useStableCallback } from "@noya-app/react-utils";
23
24
  import {
24
25
  ActivityEventsManager,
26
+ AssetTranscriptionResult,
25
27
  CreateParams,
26
- EphemeralUserDataManager,
28
+ ExtractRequestBody,
27
29
  MultiplayerPatchMetadata,
28
30
  MultiplayerStateManager,
29
31
  NoyaManager,
30
32
  PublishCallback,
31
33
  ResourceManager,
32
34
  SafeEval,
35
+ SharedConnectionDataManager,
33
36
  StateManagerOptions,
34
37
  Static,
35
38
  StreamFilter,
39
+ TranscriptionManager,
36
40
  TSchema,
37
41
  } from "@noya-app/state-manager";
38
42
  import React, {
@@ -88,70 +92,56 @@ export function resourceToCreateParameters(
88
92
  }
89
93
  }
90
94
 
91
- type BuildCreateResourcePayloadParameters = {
95
+ type ResourcePatchRequestBody = ExtractRequestBody<"PATCH /api/resources">;
96
+
97
+ type BuildResourcePatchPayloadParameters = {
92
98
  addedResources: ResourceCreate[];
93
99
  modifiedResources: ModifiedResource[];
94
- newResourceMap: ResourceCreateMap;
95
- resourceMap: ResourceMap;
96
- };
97
-
98
- type BuildCreateResourcePayloadResult = {
99
- payload: CreateResourceParametersWithoutAccessibleByFileId[];
100
- consumedModifiedResourceIds: string[];
100
+ removedResources: Resource[];
101
101
  };
102
102
 
103
- export function buildCreateResourcePayload({
103
+ export function buildResourcePatchPayload({
104
104
  addedResources,
105
105
  modifiedResources,
106
- newResourceMap,
107
- resourceMap,
108
- }: BuildCreateResourcePayloadParameters): BuildCreateResourcePayloadResult {
109
- const toCreateParameters = resourceToCreateParameters;
106
+ removedResources,
107
+ }: BuildResourcePatchPayloadParameters): ResourcePatchRequestBody {
108
+ const createEntries = addedResources.map(resourceToCreateParameters);
110
109
 
111
- const resourcesById = new Map(
112
- Object.values(resourceMap).map((resource) => [resource.id, resource])
110
+ const dedupedCreateEntries = Array.from(
111
+ new Map(createEntries.map((entry) => [entry.path, entry])).values()
113
112
  );
114
113
 
115
- const payload: CreateResourceParametersWithoutAccessibleByFileId[] = [
116
- ...addedResources.map(toCreateParameters),
117
- ];
118
-
119
- const handledModifiedResourceIds: string[] = [];
120
-
121
- const assetReplacements = modifiedResources
122
- .filter(
123
- (resource) =>
124
- resource.assetId !== undefined || resource.asset !== undefined
125
- )
126
- .map((resource) => {
127
- const previousResource = resourcesById.get(resource.id);
128
- const path = resource.path ?? previousResource?.path;
129
-
130
- if (!path) return undefined;
114
+ const updateEntries =
115
+ modifiedResources.map((resource) => {
116
+ const update: NonNullable<ResourcePatchRequestBody["update"]>[number] = {
117
+ id: resource.id,
118
+ ...(resource.path !== undefined ? { path: resource.path } : {}),
119
+ ...(resource.assetId !== undefined
120
+ ? { assetId: resource.assetId }
121
+ : {}),
122
+ ...(resource.asset ? { asset: resource.asset } : {}),
123
+ };
131
124
 
132
- const updated = newResourceMap[path];
125
+ return update;
126
+ }) ?? [];
133
127
 
134
- if (!updated || updated.type !== "asset") return undefined;
128
+ const deleteEntries: DeleteResourceParameters[] = removedResources.map(
129
+ (resource) => ({ id: resource.id })
130
+ );
135
131
 
136
- handledModifiedResourceIds.push(resource.id);
132
+ const patch: ResourcePatchRequestBody = {};
137
133
 
138
- return toCreateParameters(updated);
139
- })
140
- .filter(
141
- (
142
- resource
143
- ): resource is CreateResourceParametersWithoutAccessibleByFileId =>
144
- resource !== undefined
145
- );
146
-
147
- const deduped = new Map(
148
- [...payload, ...assetReplacements].map((item) => [item.path, item])
149
- );
134
+ if (dedupedCreateEntries.length) {
135
+ patch.create = dedupedCreateEntries;
136
+ }
137
+ if (updateEntries.length) {
138
+ patch.update = updateEntries;
139
+ }
140
+ if (deleteEntries.length) {
141
+ patch.delete = deleteEntries;
142
+ }
150
143
 
151
- return {
152
- payload: Array.from(deduped.values()),
153
- consumedModifiedResourceIds: [...new Set(handledModifiedResourceIds)],
154
- };
144
+ return patch;
155
145
  }
156
146
 
157
147
  export interface NoyaStateProviderProps<
@@ -159,8 +149,9 @@ export interface NoyaStateProviderProps<
159
149
  M extends object,
160
150
  E extends object,
161
151
  MenuT extends string,
152
+ I extends Record<string, any> = Record<string, unknown>,
162
153
  > extends Omit<
163
- UseNoyaStateOptions<S, M, E, MenuT>,
154
+ UseNoyaStateOptions<S, M, E, MenuT, I>,
164
155
  "schema" | "mergeHistoryEntries"
165
156
  > {
166
157
  children: React.ReactNode;
@@ -169,7 +160,7 @@ export interface NoyaStateProviderProps<
169
160
  }
170
161
 
171
162
  export type AnyNoyaStateContextValue = {
172
- noyaManager: NoyaManager<any, any, any, any>;
163
+ noyaManager: NoyaManager<any, any, any, any, any>;
173
164
  theme: AppTheme;
174
165
  viewType: AppViewType;
175
166
  };
@@ -202,7 +193,7 @@ export function useAnyNoyaStateContext() {
202
193
 
203
194
  export function useAnyNoyaManager() {
204
195
  const { noyaManager } = useAnyNoyaStateContext();
205
- return noyaManager as NoyaManager<any, any, any, any>;
196
+ return noyaManager as NoyaManager<any, any, any, any, any>;
206
197
  }
207
198
 
208
199
  export function useColorScheme() {
@@ -344,7 +335,7 @@ export function useConnectedUser(userId?: string | null) {
344
335
  useCallback(
345
336
  (users) => {
346
337
  return users.find((user) => {
347
- const prefix = user.id.slice(0, 8);
338
+ const prefix = user.connectionId.slice(0, 8);
348
339
  return userId?.includes(prefix);
349
340
  });
350
341
  },
@@ -353,16 +344,49 @@ export function useConnectedUser(userId?: string | null) {
353
344
  );
354
345
  }
355
346
 
356
- export function useAnyEphemeralUserData() {
347
+ export function useAnySharedConnectionData() {
357
348
  const { noyaManager } = useAnyNoyaStateContext();
358
- return noyaManager.ephemeralUserDataManager;
349
+ return noyaManager.sharedConnectionDataManager;
350
+ }
351
+
352
+ export function useEnqueueInput<
353
+ I extends Record<string, any> = Record<string, unknown>
354
+ >() {
355
+ const { noyaManager } = useAnyNoyaStateContext();
356
+ return noyaManager.enqueueInput as NoyaManager<
357
+ any,
358
+ any,
359
+ any,
360
+ any,
361
+ I
362
+ >["enqueueInput"];
363
+ }
364
+
365
+ export function useNoyaUser() {
366
+ const userManager = useUserManager();
367
+ return useObservable(userManager?.currentUser$);
368
+ }
369
+
370
+ export function useNoyaId() {
371
+ const userManager = useUserManager();
372
+ return useObservable(userManager?.currentId$);
359
373
  }
360
374
 
361
- export function useCurrentUserId() {
375
+ export function useNoyaUserId() {
362
376
  const userManager = useUserManager();
363
377
  return useObservable(userManager?.currentUserId$);
364
378
  }
365
379
 
380
+ export function useNoyaConnectionId() {
381
+ const userManager = useUserManager();
382
+ return useObservable(userManager?.currentConnectionId$);
383
+ }
384
+
385
+ export function useNoyaClientId() {
386
+ const userManager = useUserManager();
387
+ return useObservable(userManager?.currentClientId$);
388
+ }
389
+
366
390
  export function useIsProcessing() {
367
391
  const { noyaManager } = useAnyNoyaStateContext();
368
392
  return useObservable(noyaManager.isProcessing$);
@@ -389,6 +413,50 @@ export function useResourceManager(): ResourceManager {
389
413
  return noyaManager.resourceManager;
390
414
  }
391
415
 
416
+ export function useNoyaTranscriptionManager(): TranscriptionManager {
417
+ const { noyaManager } = useAnyNoyaStateContext();
418
+ return noyaManager.transcriptionManager;
419
+ }
420
+
421
+ type UseNoyaAssetTranscriptionOptions = {
422
+ endpoint?: string;
423
+ apiKey?: string;
424
+ };
425
+
426
+ /**
427
+ * Returns a text transcription for the given assetId.
428
+ *
429
+ * - This API is available when running your app on noya.io, not when running it locally.
430
+ * - An asset must first be uploaded via the `useAssetManager().create()` method before
431
+ * it can be transcribed via this API.
432
+ * - The asset must be a valid audio or video file.
433
+ */
434
+ export function useNoyaAssetTranscription(
435
+ assetId: string,
436
+ options?: UseNoyaAssetTranscriptionOptions
437
+ ): AssetTranscriptionResult;
438
+ export function useNoyaAssetTranscription(
439
+ assetId?: string,
440
+ options?: UseNoyaAssetTranscriptionOptions
441
+ ): AssetTranscriptionResult | undefined;
442
+ export function useNoyaAssetTranscription(
443
+ assetId?: string,
444
+ options?: UseNoyaAssetTranscriptionOptions
445
+ ): AssetTranscriptionResult | undefined {
446
+ const transcriptionManager = useNoyaTranscriptionManager();
447
+
448
+ const observable = useMemo(() => {
449
+ if (!assetId) return undefined;
450
+
451
+ return transcriptionManager.getAssetTranscription$(assetId, {
452
+ endpoint: options?.endpoint,
453
+ apiKey: options?.apiKey,
454
+ });
455
+ }, [transcriptionManager, assetId, options?.endpoint, options?.apiKey]);
456
+
457
+ return useObservable(observable);
458
+ }
459
+
392
460
  // export function useResources(): Resource[] {
393
461
  // const { noyaManager } = useAnyNoyaStateContext();
394
462
  // const resources = useObservable(noyaManager.resourceManager.resources$);
@@ -431,29 +499,20 @@ export function useResources({
431
499
  const { addedResources, removedResources, modifiedResources } =
432
500
  diffResourceMaps(resourceMap, newResourceMap, "id");
433
501
 
434
- const { payload: createPayload, consumedModifiedResourceIds } =
435
- buildCreateResourcePayload({
436
- addedResources,
437
- modifiedResources,
438
- newResourceMap,
439
- resourceMap,
440
- });
502
+ const patchPayload = buildResourcePatchPayload({
503
+ addedResources,
504
+ modifiedResources,
505
+ removedResources,
506
+ });
441
507
 
442
- if (createPayload.length > 0) {
443
- await resourceManager.createResource(createPayload);
444
- }
445
-
446
- const consumedModifiedResourceIdsSet = new Set(
447
- consumedModifiedResourceIds
448
- );
508
+ const hasPatchOperations =
509
+ (patchPayload.create?.length ?? 0) > 0 ||
510
+ (patchPayload.update?.length ?? 0) > 0 ||
511
+ (patchPayload.delete?.length ?? 0) > 0;
449
512
 
450
- const remainingModifiedResources = modifiedResources.filter(
451
- (resource) => !consumedModifiedResourceIdsSet.has(resource.id)
452
- );
453
-
454
- await resourceManager.deleteResource(
455
- removedResources.map((resource) => ({ id: resource.id }))
456
- );
513
+ if (hasPatchOperations) {
514
+ await resourceManager.patchResources(patchPayload);
515
+ }
457
516
 
458
517
  if (shouldDeleteAssets) {
459
518
  for (const resource of removedResources) {
@@ -462,17 +521,6 @@ export function useResources({
462
521
  }
463
522
  }
464
523
  }
465
-
466
- await Promise.all(
467
- remainingModifiedResources.map(({ id, path, assetId, asset }) =>
468
- resourceManager.updateResource({
469
- id,
470
- path,
471
- assetId,
472
- ...(assetId ? {} : asset ? { asset } : {}),
473
- })
474
- )
475
- );
476
524
  },
477
525
  [resourceMap, resourceManager, shouldDeleteAssets, assetManager]
478
526
  );
@@ -535,6 +583,7 @@ export function createNoyaContext<
535
583
  M extends object = object,
536
584
  E extends object = object,
537
585
  MenuT extends string = string,
586
+ I extends Record<string, any> = Record<string, unknown>,
538
587
  >({
539
588
  schema,
540
589
  mergeHistoryEntries,
@@ -557,7 +606,7 @@ export function createNoyaContext<
557
606
  >;
558
607
 
559
608
  const NoyaStateContext = AnyNoyaStateContext as React.Context<
560
- NoyaManager<S, M, E> | undefined
609
+ NoyaManager<S, M, E, MenuT, I> | undefined
561
610
  >;
562
611
 
563
612
  function NoyaContextProvider({
@@ -578,12 +627,13 @@ export function createNoyaContext<
578
627
  children,
579
628
  initialState,
580
629
  ...options
581
- }: NoyaStateProviderProps<S, M, E, MenuT>) {
630
+ }: NoyaStateProviderProps<S, M, E, MenuT, I>) {
582
631
  const [, , { noyaManager, theme, viewType }] = useNoyaStateInternal<
583
632
  S,
584
633
  M,
585
634
  E,
586
- MenuT
635
+ MenuT,
636
+ I
587
637
  >(initialState, {
588
638
  schema,
589
639
  mergeHistoryEntries,
@@ -730,9 +780,9 @@ export function createNoyaContext<
730
780
  >;
731
781
  }
732
782
 
733
- function useEphemeralUserDataManager() {
783
+ function useSharedConnectionDataManager() {
734
784
  const { noyaManager } = useAnyNoyaStateContext();
735
- return noyaManager.ephemeralUserDataManager as EphemeralUserDataManager<E>;
785
+ return noyaManager.sharedConnectionDataManager as SharedConnectionDataManager<E>;
736
786
  }
737
787
 
738
788
  function useNoyaManager() {
@@ -740,7 +790,8 @@ export function createNoyaContext<
740
790
  S,
741
791
  PartialM,
742
792
  E,
743
- MenuT
793
+ MenuT,
794
+ I
744
795
  >;
745
796
  }
746
797
 
@@ -812,7 +863,7 @@ export function createNoyaContext<
812
863
  useSetValue,
813
864
  useValueState,
814
865
  useStateManager,
815
- useEphemeralUserDataManager,
866
+ useSharedConnectionDataManager,
816
867
  useLeftMenuItems,
817
868
  useSetLeftMenuItems,
818
869
  useRightMenuItems,
@@ -14,6 +14,7 @@ it("gets AppData with no data", () => {
14
14
  initialState,
15
15
  inspector: false,
16
16
  isDemo: false,
17
+ access: "write",
17
18
  });
18
19
  });
19
20
 
@@ -39,6 +40,7 @@ it("gets AppData with data param", () => {
39
40
  initialState: { foo: "bar" },
40
41
  inspector: false,
41
42
  isDemo: false,
43
+ access: "write",
42
44
  });
43
45
  });
44
46
 
@@ -53,6 +55,7 @@ it("uses initial state if data doesn't parse", () => {
53
55
  initialState: { foo: "bar" },
54
56
  inspector: false,
55
57
  isDemo: false,
58
+ access: "write",
56
59
  });
57
60
  });
58
61
 
@@ -71,6 +74,7 @@ it("gets AppData with schema", () => {
71
74
  initialState: { foo: "bar" },
72
75
  inspector: false,
73
76
  isDemo: false,
77
+ access: "write",
74
78
  });
75
79
  });
76
80
 
@@ -130,6 +134,7 @@ it("gets AppData with function initial state", () => {
130
134
  initialState: { foo: "bar" },
131
135
  inspector: false,
132
136
  isDemo: false,
137
+ access: "write",
133
138
  });
134
139
  });
135
140
 
@@ -158,6 +163,7 @@ it("even if initial state does not match schema, make sure we use multiplayer ur
158
163
  inspector: false,
159
164
  multiplayerUrl: "https://example.com",
160
165
  isDemo: false,
166
+ access: "write",
161
167
  });
162
168
  });
163
169
 
@@ -2,14 +2,9 @@ import {
2
2
  ModifiedResource,
3
3
  Resource,
4
4
  ResourceCreate,
5
- ResourceCreateMap,
6
- ResourceMap,
7
5
  } from "@noya-app/noya-schemas";
8
6
  import { describe, expect, it } from "bun:test";
9
- import {
10
- buildCreateResourcePayload,
11
- resourceToCreateParameters,
12
- } from "../NoyaStateContext";
7
+ import { buildResourcePatchPayload } from "../NoyaStateContext";
13
8
 
14
9
  const ISO_DATE = "2024-01-01T00:00:00.000Z";
15
10
 
@@ -82,25 +77,23 @@ describe("resource payload helpers", () => {
82
77
  it("returns create parameters for added resources", () => {
83
78
  const addedResource = createDirectoryResourceCreate();
84
79
 
85
- const result = buildCreateResourcePayload({
80
+ const result = buildResourcePatchPayload({
86
81
  addedResources: [addedResource],
87
82
  modifiedResources: [],
88
- newResourceMap: {
89
- [addedResource.path]: addedResource,
90
- } satisfies ResourceCreateMap,
91
- resourceMap: {},
83
+ removedResources: [],
92
84
  });
93
85
 
94
- expect(result.payload).toEqual([
86
+ expect(result.create).toEqual([
95
87
  {
96
88
  path: "docs",
97
89
  type: "directory",
98
90
  },
99
91
  ]);
100
- expect(result.consumedModifiedResourceIds).toEqual([]);
92
+ expect(result.update).toBeUndefined();
93
+ expect(result.delete).toBeUndefined();
101
94
  });
102
95
 
103
- it("includes asset replacements when a modified resource swaps the asset", () => {
96
+ it("includes update entries when a modified resource swaps the asset", () => {
104
97
  const existingResource = createAssetResource({
105
98
  id: "existing-resource",
106
99
  stableId: "existing-stable",
@@ -115,117 +108,31 @@ describe("resource payload helpers", () => {
115
108
  assetId: "asset-new",
116
109
  });
117
110
 
118
- const result = buildCreateResourcePayload({
111
+ const result = buildResourcePatchPayload({
119
112
  addedResources: [],
120
113
  modifiedResources: [
121
114
  {
122
115
  id: existingResource.id,
123
116
  stableId: existingResource.stableId,
124
117
  assetId: updatedResource.assetId,
125
- } satisfies ModifiedResource,
126
- ],
127
- newResourceMap: {
128
- [updatedResource.path]: updatedResource,
129
- } satisfies ResourceCreateMap,
130
- resourceMap: {
131
- [existingResource.path]: existingResource,
132
- } satisfies ResourceMap,
133
- });
134
-
135
- expect(result.payload).toEqual([
136
- resourceToCreateParameters(updatedResource),
137
- ]);
138
- expect(result.consumedModifiedResourceIds).toEqual([
139
- existingResource.id,
140
- ]);
141
- });
142
-
143
- it("includes asset replacements when a modified resource provides inline asset data", () => {
144
- const existingResource = createAssetResource({
145
- id: "existing-resource",
146
- stableId: "existing-stable",
147
- path: "images/logo.png",
148
- assetId: "asset-old",
149
- });
150
-
151
- const updatedResource = createAssetResourceCreate({
152
- id: "existing-resource",
153
- stableId: "existing-stable",
154
- path: "images/logo.png",
155
- assetId: "asset-old",
156
- asset: {
157
- content: "ZGF0YQ==",
158
- contentType: "image/png",
159
- encoding: "base64" as const,
160
- },
161
- });
162
-
163
- const result = buildCreateResourcePayload({
164
- addedResources: [],
165
- modifiedResources: [
166
- {
167
- id: existingResource.id,
168
- stableId: existingResource.stableId,
169
118
  asset: updatedResource.asset,
170
119
  } satisfies ModifiedResource,
171
120
  ],
172
- newResourceMap: {
173
- [updatedResource.path]: updatedResource,
174
- } satisfies ResourceCreateMap,
175
- resourceMap: {
176
- [existingResource.path]: existingResource,
177
- } satisfies ResourceMap,
121
+ removedResources: [],
178
122
  });
179
123
 
180
- expect(result.payload).toEqual([
181
- resourceToCreateParameters(updatedResource),
182
- ]);
183
- expect(result.consumedModifiedResourceIds).toEqual([
184
- existingResource.id,
185
- ]);
186
- });
187
-
188
- it("deduplicates payload entries by path", () => {
189
- const existingResource = createAssetResource({
190
- id: "existing-resource",
191
- stableId: "existing-stable",
192
- path: "shared/path",
193
- assetId: "asset-old",
194
- });
195
-
196
- const updatedResource = createAssetResourceCreate({
197
- id: "new-resource",
198
- stableId: "new-stable",
199
- path: "shared/path",
200
- assetId: "asset-new",
201
- });
202
-
203
- const result = buildCreateResourcePayload({
204
- addedResources: [updatedResource],
205
- modifiedResources: [
206
- {
207
- id: existingResource.id,
208
- stableId: existingResource.stableId,
209
- assetId: updatedResource.assetId,
210
- } satisfies ModifiedResource,
211
- ],
212
- newResourceMap: {
213
- [updatedResource.path]: updatedResource,
214
- } satisfies ResourceCreateMap,
215
- resourceMap: {
216
- [existingResource.path]: existingResource,
217
- } satisfies ResourceMap,
218
- });
219
-
220
- expect(result.payload).toEqual([
221
- resourceToCreateParameters(updatedResource),
222
- ]);
223
- expect(result.consumedModifiedResourceIds).toEqual([
224
- existingResource.id,
124
+ expect(result.update).toEqual([
125
+ {
126
+ id: existingResource.id,
127
+ assetId: updatedResource.assetId,
128
+ asset: updatedResource.asset,
129
+ },
225
130
  ]);
131
+ expect(result.create).toBeUndefined();
132
+ expect(result.delete).toBeUndefined();
226
133
  });
227
134
 
228
- it("excludes modified resources without asset changes from the consumed list", () => {
135
+ it("includes delete entries for removed resources", () => {
229
136
  const existingResource = createAssetResource({
230
137
  id: "existing-resource",
231
138
  stableId: "existing-stable",
@@ -233,31 +140,14 @@ describe("resource payload helpers", () => {
233
140
  assetId: "asset-old",
234
141
  });
235
142
 
236
- const updatedResource = createAssetResourceCreate({
237
- id: "existing-resource",
238
- stableId: "existing-stable",
239
- path: "images/logo.png",
240
- assetId: "asset-old",
241
- });
242
-
243
- const result = buildCreateResourcePayload({
143
+ const result = buildResourcePatchPayload({
244
144
  addedResources: [],
245
- modifiedResources: [
246
- {
247
- id: existingResource.id,
248
- stableId: existingResource.stableId,
249
- path: updatedResource.path,
250
- } satisfies ModifiedResource,
251
- ],
252
- newResourceMap: {
253
- [updatedResource.path]: updatedResource,
254
- } satisfies ResourceCreateMap,
255
- resourceMap: {
256
- [existingResource.path]: existingResource,
257
- } satisfies ResourceMap,
145
+ modifiedResources: [],
146
+ removedResources: [existingResource],
258
147
  });
259
148
 
260
- expect(result.payload).toEqual([]);
261
- expect(result.consumedModifiedResourceIds).toEqual([]);
149
+ expect(result.delete).toEqual([{ id: existingResource.id }]);
150
+ expect(result.create).toBeUndefined();
151
+ expect(result.update).toBeUndefined();
262
152
  });
263
153
  });