@noya-app/noya-multiplayer-react 0.1.66 → 0.1.68
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/.turbo/turbo-build.log +11 -11
- package/CHANGELOG.md +15 -0
- package/dist/index.bundle.js +19 -19
- package/dist/index.d.mts +95 -25
- package/dist/index.d.ts +95 -25
- package/dist/index.js +419 -177
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +381 -145
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/NoyaStateContext.tsx +179 -90
- package/src/__tests__/NoyaStateContext.test.ts +3 -2
- package/src/__tests__/resourcePayload.test.ts +263 -0
- package/src/__tests__/serialize.test.ts +8 -6
- package/src/hooks.ts +46 -47
- package/src/index.ts +1 -0
- package/src/inspector/StateInspector.tsx +16 -7
- package/src/inspector/serialization.ts +6 -12
- package/src/inspector/useStateInspector.tsx +15 -7
- package/src/noyaApp.ts +37 -17
- package/src/singleton.tsx +140 -0
package/dist/index.mjs
CHANGED
|
@@ -3982,6 +3982,7 @@ var activityEventSchema = Type.Object({
|
|
|
3982
3982
|
// ../noya-schemas/src/asset.ts
|
|
3983
3983
|
var assetSchema = Type.Object({
|
|
3984
3984
|
id: Type.String(),
|
|
3985
|
+
stableId: Type.String(),
|
|
3985
3986
|
url: Type.String(),
|
|
3986
3987
|
createdAt: Type.String(),
|
|
3987
3988
|
size: Type.Number(),
|
|
@@ -4487,6 +4488,26 @@ var flatResourceSchema = Type.Object({
|
|
|
4487
4488
|
fileId: Nullable(Type.String()),
|
|
4488
4489
|
resourceId: Nullable(Type.String())
|
|
4489
4490
|
});
|
|
4491
|
+
function getChangedResourceProperties({
|
|
4492
|
+
oldResource,
|
|
4493
|
+
newResource,
|
|
4494
|
+
oldPath,
|
|
4495
|
+
newPath
|
|
4496
|
+
}) {
|
|
4497
|
+
const changed = {};
|
|
4498
|
+
if (newPath !== void 0 && (oldPath ?? oldResource.path) !== newPath) {
|
|
4499
|
+
changed.path = newPath;
|
|
4500
|
+
}
|
|
4501
|
+
const oldAssetId = oldResource.type === "asset" ? oldResource.assetId : void 0;
|
|
4502
|
+
const newAssetId = newResource.type === "asset" ? newResource.assetId : void 0;
|
|
4503
|
+
if (oldAssetId !== newAssetId) {
|
|
4504
|
+
changed.assetId = newAssetId;
|
|
4505
|
+
}
|
|
4506
|
+
if (newResource.type === "asset" && newResource.asset !== void 0) {
|
|
4507
|
+
changed.asset = newResource.asset;
|
|
4508
|
+
}
|
|
4509
|
+
return changed;
|
|
4510
|
+
}
|
|
4490
4511
|
function diffResourceMaps(resourceMap, newResourceMap, idProperty) {
|
|
4491
4512
|
const oldIdToPathMap = new Map(
|
|
4492
4513
|
Object.entries(resourceMap).map(([path2, entity]) => [
|
|
@@ -4513,7 +4534,7 @@ function diffResourceMaps(resourceMap, newResourceMap, idProperty) {
|
|
|
4513
4534
|
const removedResources = Object.values(resourceMap).filter(
|
|
4514
4535
|
(entity) => !newIds.has(entity[idProperty])
|
|
4515
4536
|
);
|
|
4516
|
-
const
|
|
4537
|
+
const sameIdModifiedResources = [...sameIds].flatMap((id) => {
|
|
4517
4538
|
const oldResource = Object.values(resourceMap).find(
|
|
4518
4539
|
(resource) => resource[idProperty] === id
|
|
4519
4540
|
);
|
|
@@ -4523,17 +4544,54 @@ function diffResourceMaps(resourceMap, newResourceMap, idProperty) {
|
|
|
4523
4544
|
if (!oldResource || !newResource) return [];
|
|
4524
4545
|
const oldPath = oldIdToPathMap.get(id);
|
|
4525
4546
|
const newPath = newIdToPathMap.get(id);
|
|
4526
|
-
const
|
|
4527
|
-
|
|
4528
|
-
|
|
4529
|
-
|
|
4530
|
-
|
|
4531
|
-
|
|
4532
|
-
};
|
|
4547
|
+
const changedProperties = getChangedResourceProperties({
|
|
4548
|
+
oldResource,
|
|
4549
|
+
newResource,
|
|
4550
|
+
oldPath,
|
|
4551
|
+
newPath
|
|
4552
|
+
});
|
|
4533
4553
|
if (Object.keys(changedProperties).length === 0) return [];
|
|
4534
4554
|
return [{ id, stableId: newResource.stableId, ...changedProperties }];
|
|
4535
4555
|
});
|
|
4536
|
-
|
|
4556
|
+
const removedResourcesByPath = new Map(
|
|
4557
|
+
removedResources.map((resource) => [resource.path, resource])
|
|
4558
|
+
);
|
|
4559
|
+
const swappedPaths = /* @__PURE__ */ new Set();
|
|
4560
|
+
const swappedModifiedResources = [];
|
|
4561
|
+
for (const addedResource of addedResources) {
|
|
4562
|
+
const existingResource = removedResourcesByPath.get(addedResource.path);
|
|
4563
|
+
if (!existingResource) continue;
|
|
4564
|
+
if (existingResource.type !== addedResource.type) continue;
|
|
4565
|
+
if (existingResource[idProperty] === addedResource[idProperty]) continue;
|
|
4566
|
+
swappedPaths.add(addedResource.path);
|
|
4567
|
+
const changedProperties = getChangedResourceProperties({
|
|
4568
|
+
oldResource: existingResource,
|
|
4569
|
+
newResource: addedResource,
|
|
4570
|
+
oldPath: existingResource.path,
|
|
4571
|
+
newPath: addedResource.path
|
|
4572
|
+
});
|
|
4573
|
+
if (Object.keys(changedProperties).length === 0) continue;
|
|
4574
|
+
const id = existingResource[idProperty];
|
|
4575
|
+
swappedModifiedResources.push({
|
|
4576
|
+
id,
|
|
4577
|
+
stableId: existingResource.stableId,
|
|
4578
|
+
...changedProperties
|
|
4579
|
+
});
|
|
4580
|
+
}
|
|
4581
|
+
const filteredAddedResources = addedResources.filter(
|
|
4582
|
+
(resource) => !swappedPaths.has(resource.path)
|
|
4583
|
+
);
|
|
4584
|
+
const filteredRemovedResources = removedResources.filter(
|
|
4585
|
+
(resource) => !swappedPaths.has(resource.path)
|
|
4586
|
+
);
|
|
4587
|
+
return {
|
|
4588
|
+
addedResources: filteredAddedResources,
|
|
4589
|
+
removedResources: filteredRemovedResources,
|
|
4590
|
+
modifiedResources: [
|
|
4591
|
+
...sameIdModifiedResources,
|
|
4592
|
+
...swappedModifiedResources
|
|
4593
|
+
]
|
|
4594
|
+
};
|
|
4537
4595
|
}
|
|
4538
4596
|
|
|
4539
4597
|
// ../noya-schemas/src/resourceTree.ts
|
|
@@ -4554,7 +4612,7 @@ import {
|
|
|
4554
4612
|
Observable
|
|
4555
4613
|
} from "@noya-app/observable";
|
|
4556
4614
|
import { useJsonMemo, useStableCallback } from "@noya-app/react-utils";
|
|
4557
|
-
import
|
|
4615
|
+
import React17, {
|
|
4558
4616
|
createContext,
|
|
4559
4617
|
useCallback as useCallback3,
|
|
4560
4618
|
useContext,
|
|
@@ -4568,6 +4626,7 @@ import {
|
|
|
4568
4626
|
createOrCastValue,
|
|
4569
4627
|
isEmbeddedApp,
|
|
4570
4628
|
localStorageSync,
|
|
4629
|
+
NoyaManager as NoyaManager3,
|
|
4571
4630
|
parentFrameSync,
|
|
4572
4631
|
stubSync as stubSync2,
|
|
4573
4632
|
TypeGuard,
|
|
@@ -4714,6 +4773,26 @@ var FILE_TYPE_TO_EXTENSION = {
|
|
|
4714
4773
|
};
|
|
4715
4774
|
var FILE_EXTENSION_TO_TYPE = invert(FILE_TYPE_TO_EXTENSION);
|
|
4716
4775
|
|
|
4776
|
+
// ../noya-utils/src/memoize.ts
|
|
4777
|
+
function memoize(f) {
|
|
4778
|
+
const intermediateCache = /* @__PURE__ */ new Map();
|
|
4779
|
+
const cache = /* @__PURE__ */ new Map();
|
|
4780
|
+
let intermediateCacheIndex = 0;
|
|
4781
|
+
return (...values) => {
|
|
4782
|
+
let key = "";
|
|
4783
|
+
for (const value of values) {
|
|
4784
|
+
if (!intermediateCache.has(value)) {
|
|
4785
|
+
intermediateCache.set(value, `${intermediateCacheIndex++}`);
|
|
4786
|
+
}
|
|
4787
|
+
key += intermediateCache.get(value) + ":";
|
|
4788
|
+
}
|
|
4789
|
+
if (!cache.has(key)) {
|
|
4790
|
+
cache.set(key, f(...values));
|
|
4791
|
+
}
|
|
4792
|
+
return cache.get(key);
|
|
4793
|
+
};
|
|
4794
|
+
}
|
|
4795
|
+
|
|
4717
4796
|
// ../noya-utils/src/memoizeDeep.ts
|
|
4718
4797
|
var TOKEN_OBJECT = Symbol("object");
|
|
4719
4798
|
var TOKEN_ARRAY = Symbol("array");
|
|
@@ -5940,19 +6019,17 @@ async function importAll(buffer, noyaManager, {
|
|
|
5940
6019
|
}
|
|
5941
6020
|
if (assets.length) {
|
|
5942
6021
|
await Promise.all(
|
|
5943
|
-
noyaManager.assetManager.assets$.get().map((asset) => noyaManager.assetManager.delete(asset.
|
|
6022
|
+
noyaManager.assetManager.assets$.get().map((asset) => noyaManager.assetManager.delete(asset.stableId))
|
|
5944
6023
|
);
|
|
5945
|
-
|
|
6024
|
+
await Promise.all(
|
|
5946
6025
|
assets.map(async (asset) => {
|
|
5947
|
-
|
|
6026
|
+
await noyaManager.assetManager.create({
|
|
5948
6027
|
data: assetMap[asset.id],
|
|
5949
|
-
contentType: asset.contentType
|
|
6028
|
+
contentType: asset.contentType,
|
|
6029
|
+
stableId: asset.stableId
|
|
5950
6030
|
});
|
|
5951
|
-
return [asset.id, newAsset.id];
|
|
5952
6031
|
})
|
|
5953
6032
|
);
|
|
5954
|
-
const replacementMap = Object.fromEntries(idPairs);
|
|
5955
|
-
state = replaceDeep(state, replacementMap);
|
|
5956
6033
|
}
|
|
5957
6034
|
noyaManager.initialState = state;
|
|
5958
6035
|
noyaManager.forceInit();
|
|
@@ -6468,7 +6545,14 @@ var StateInspector = memoGeneric(function StateInspector2({
|
|
|
6468
6545
|
"Upload"
|
|
6469
6546
|
))
|
|
6470
6547
|
},
|
|
6471
|
-
/* @__PURE__ */ React14.createElement(StateInspectorDisclosureRowInner, null, assets.map((asset) => /* @__PURE__ */ React14.createElement(StateInspectorRow, { key: asset.id, colorScheme }, /* @__PURE__ */ React14.createElement(
|
|
6548
|
+
/* @__PURE__ */ React14.createElement(StateInspectorDisclosureRowInner, null, assets.map((asset) => /* @__PURE__ */ React14.createElement(StateInspectorRow, { key: asset.id, colorScheme }, /* @__PURE__ */ React14.createElement(
|
|
6549
|
+
ObjectInspector4,
|
|
6550
|
+
{
|
|
6551
|
+
name: asset.id,
|
|
6552
|
+
data: truncateAsset(asset),
|
|
6553
|
+
theme
|
|
6554
|
+
}
|
|
6555
|
+
), /* @__PURE__ */ React14.createElement(
|
|
6472
6556
|
StateInspectorButton,
|
|
6473
6557
|
{
|
|
6474
6558
|
theme,
|
|
@@ -6493,10 +6577,8 @@ var StateInspector = memoGeneric(function StateInspector2({
|
|
|
6493
6577
|
"Are you sure you want to delete all resources?"
|
|
6494
6578
|
);
|
|
6495
6579
|
if (!ok) return;
|
|
6496
|
-
await
|
|
6497
|
-
resources.map(
|
|
6498
|
-
(resource) => resourceManager.deleteResource({ id: resource.id })
|
|
6499
|
-
)
|
|
6580
|
+
await resourceManager.deleteResource(
|
|
6581
|
+
resources.map((resource) => ({ id: resource.id }))
|
|
6500
6582
|
);
|
|
6501
6583
|
}
|
|
6502
6584
|
},
|
|
@@ -6709,6 +6791,12 @@ var StateInspector = memoGeneric(function StateInspector2({
|
|
|
6709
6791
|
)
|
|
6710
6792
|
);
|
|
6711
6793
|
});
|
|
6794
|
+
var truncateAsset = memoize((asset) => {
|
|
6795
|
+
if (asset.url.startsWith("data:") || asset.url.startsWith("blob:")) {
|
|
6796
|
+
return { ...asset, url: ellipsis(asset.url, 40) };
|
|
6797
|
+
}
|
|
6798
|
+
return asset;
|
|
6799
|
+
});
|
|
6712
6800
|
|
|
6713
6801
|
// src/inspector/useStateInspector.tsx
|
|
6714
6802
|
function createShadowRootElement() {
|
|
@@ -6719,6 +6807,17 @@ function createShadowRootElement() {
|
|
|
6719
6807
|
shadowRoot.appendChild(container);
|
|
6720
6808
|
return { host, container };
|
|
6721
6809
|
}
|
|
6810
|
+
function createStateInspectorRoot() {
|
|
6811
|
+
const { host, container } = createShadowRootElement();
|
|
6812
|
+
const root = createRoot(container);
|
|
6813
|
+
document.body.appendChild(host);
|
|
6814
|
+
return {
|
|
6815
|
+
root,
|
|
6816
|
+
unmount: () => {
|
|
6817
|
+
document.body.removeChild(host);
|
|
6818
|
+
}
|
|
6819
|
+
};
|
|
6820
|
+
}
|
|
6722
6821
|
function useStateInspector({
|
|
6723
6822
|
noyaManager,
|
|
6724
6823
|
disabled = false,
|
|
@@ -6728,13 +6827,9 @@ function useStateInspector({
|
|
|
6728
6827
|
const [root, setRoot] = React15.useState(null);
|
|
6729
6828
|
useIsomorphicLayoutEffect(() => {
|
|
6730
6829
|
if (disabled) return;
|
|
6731
|
-
const {
|
|
6732
|
-
const root2 = createRoot(container);
|
|
6733
|
-
document.body.appendChild(host);
|
|
6830
|
+
const { root: root2, unmount } = createStateInspectorRoot();
|
|
6734
6831
|
setRoot(root2);
|
|
6735
|
-
return
|
|
6736
|
-
document.body.removeChild(host);
|
|
6737
|
-
};
|
|
6832
|
+
return unmount;
|
|
6738
6833
|
}, [disabled]);
|
|
6739
6834
|
useIsomorphicLayoutEffect(() => {
|
|
6740
6835
|
if (!root) return;
|
|
@@ -6752,22 +6847,18 @@ function useStateInspector({
|
|
|
6752
6847
|
}
|
|
6753
6848
|
|
|
6754
6849
|
// src/hooks.ts
|
|
6755
|
-
function
|
|
6756
|
-
const
|
|
6757
|
-
() =>
|
|
6758
|
-
[stateManager, path2]
|
|
6850
|
+
function useManagedState(createInitialState, options) {
|
|
6851
|
+
const [stateManager] = useState2(
|
|
6852
|
+
() => new StateManager(createInitialState(), options)
|
|
6759
6853
|
);
|
|
6760
|
-
|
|
6854
|
+
const getSnapshot = useCallback2(() => {
|
|
6855
|
+
return stateManager.getState();
|
|
6856
|
+
}, [stateManager]);
|
|
6857
|
+
const state = useSyncExternalStore2(
|
|
6761
6858
|
stateManager.addListener,
|
|
6762
6859
|
getSnapshot,
|
|
6763
6860
|
getSnapshot
|
|
6764
6861
|
);
|
|
6765
|
-
}
|
|
6766
|
-
function useManagedState(createInitialState, options) {
|
|
6767
|
-
const [stateManager] = useState2(
|
|
6768
|
-
() => new StateManager(createInitialState(), options)
|
|
6769
|
-
);
|
|
6770
|
-
const state = useSyncStateManager(stateManager);
|
|
6771
6862
|
const setState = useCallback2(
|
|
6772
6863
|
(...args) => {
|
|
6773
6864
|
const [metadata, action] = args.length === 1 ? [void 0, args[0]] : args;
|
|
@@ -6810,15 +6901,7 @@ function useManagedHistory(stateManager) {
|
|
|
6810
6901
|
stateManager.getHistorySnapshot
|
|
6811
6902
|
);
|
|
6812
6903
|
}
|
|
6813
|
-
function
|
|
6814
|
-
const {
|
|
6815
|
-
sync = stubSync(),
|
|
6816
|
-
inspector,
|
|
6817
|
-
...rest
|
|
6818
|
-
} = options ?? {};
|
|
6819
|
-
const [noyaManager] = useState2(
|
|
6820
|
-
() => new NoyaManager2(initialState, rest)
|
|
6821
|
-
);
|
|
6904
|
+
function useBindNoyaManager(noyaManager, options) {
|
|
6822
6905
|
const state = useObservable(
|
|
6823
6906
|
noyaManager.multiplayerStateManager.optimisticState$
|
|
6824
6907
|
);
|
|
@@ -6842,7 +6925,7 @@ function useMultiplayerState(initialState, options) {
|
|
|
6842
6925
|
assets
|
|
6843
6926
|
};
|
|
6844
6927
|
}, [noyaManager, assets]);
|
|
6845
|
-
const syncRef = useRef2(sync);
|
|
6928
|
+
const syncRef = useRef2(options?.sync);
|
|
6846
6929
|
useEffect3(() => {
|
|
6847
6930
|
if (syncRef.current) {
|
|
6848
6931
|
return syncRef.current({ noyaManager });
|
|
@@ -6851,11 +6934,22 @@ function useMultiplayerState(initialState, options) {
|
|
|
6851
6934
|
useErrorOverlay(noyaManager);
|
|
6852
6935
|
useStateInspector({
|
|
6853
6936
|
noyaManager,
|
|
6854
|
-
disabled: !inspector,
|
|
6855
|
-
...typeof inspector === "object" && inspector
|
|
6937
|
+
disabled: !options?.inspector,
|
|
6938
|
+
...typeof options?.inspector === "object" && options?.inspector
|
|
6856
6939
|
});
|
|
6857
6940
|
return [state, noyaManager.multiplayerStateManager.setState, extras];
|
|
6858
6941
|
}
|
|
6942
|
+
function useMultiplayerState(initialState, options) {
|
|
6943
|
+
const {
|
|
6944
|
+
sync = stubSync(),
|
|
6945
|
+
inspector,
|
|
6946
|
+
...rest
|
|
6947
|
+
} = options ?? {};
|
|
6948
|
+
const [noyaManager] = useState2(
|
|
6949
|
+
() => new NoyaManager2(initialState, rest)
|
|
6950
|
+
);
|
|
6951
|
+
return useBindNoyaManager(noyaManager, { sync, inspector });
|
|
6952
|
+
}
|
|
6859
6953
|
function useErrorOverlay(noyaManager) {
|
|
6860
6954
|
const unrecoverableError = useObservable(noyaManager.unrecoverableError);
|
|
6861
6955
|
useEffect3(() => {
|
|
@@ -6911,7 +7005,11 @@ function getAppData(initialState, schema, options) {
|
|
|
6911
7005
|
appData.initialState = enforceSchema(appData.initialState, schema);
|
|
6912
7006
|
return appData;
|
|
6913
7007
|
}
|
|
6914
|
-
function
|
|
7008
|
+
function getSyncAdapter(params) {
|
|
7009
|
+
const { multiplayerUrl, offlineStorageKey, debug } = params ?? {};
|
|
7010
|
+
return isEmbeddedApp() ? parentFrameSync({ debug }) : multiplayerUrl ? webSocketSync({ url: multiplayerUrl, debug }) : offlineStorageKey ? localStorageSync({ key: offlineStorageKey }) : stubSync2();
|
|
7011
|
+
}
|
|
7012
|
+
function useNoyaStateInternal(...args) {
|
|
6915
7013
|
const [initialState, options] = typeof args[0] === "object" && args[0] !== null && "schema" in args[0] && TypeGuard.IsSchema(args[0].schema) ? [null, args[0]] : [args[0], args[1]];
|
|
6916
7014
|
const [
|
|
6917
7015
|
{
|
|
@@ -6927,13 +7025,16 @@ function useNoyaState(...args) {
|
|
|
6927
7025
|
});
|
|
6928
7026
|
});
|
|
6929
7027
|
const sync = useMemo3(() => {
|
|
6930
|
-
return
|
|
6931
|
-
|
|
7028
|
+
return getSyncAdapter({
|
|
7029
|
+
multiplayerUrl,
|
|
7030
|
+
offlineStorageKey: options?.offlineStorageKey,
|
|
6932
7031
|
debug: options?.debug
|
|
6933
|
-
})
|
|
7032
|
+
});
|
|
6934
7033
|
}, [multiplayerUrl, options?.offlineStorageKey, options?.debug]);
|
|
6935
|
-
const
|
|
6936
|
-
|
|
7034
|
+
const [noyaManager] = useState3(
|
|
7035
|
+
() => new NoyaManager3(noyaAppInitialState, options)
|
|
7036
|
+
);
|
|
7037
|
+
const result = useBindNoyaManager(noyaManager, {
|
|
6937
7038
|
inspector: options?.inspector ?? inspector,
|
|
6938
7039
|
sync: options?.sync ?? sync
|
|
6939
7040
|
});
|
|
@@ -6944,11 +7045,166 @@ function useNoyaState(...args) {
|
|
|
6944
7045
|
return [result[0], result[1], mergedExtras];
|
|
6945
7046
|
}
|
|
6946
7047
|
|
|
7048
|
+
// src/singleton.tsx
|
|
7049
|
+
import {
|
|
7050
|
+
NoyaManager as NoyaManager4
|
|
7051
|
+
} from "@noya-app/state-manager";
|
|
7052
|
+
import React16 from "react";
|
|
7053
|
+
var noyaManagerSingleton;
|
|
7054
|
+
var noyaSingletonBindings;
|
|
7055
|
+
function initializeNoyaSingleton(options) {
|
|
7056
|
+
if (noyaManagerSingleton) {
|
|
7057
|
+
throw new Error(
|
|
7058
|
+
"Noya has already been initialized. Call `useNoyaState` instead."
|
|
7059
|
+
);
|
|
7060
|
+
}
|
|
7061
|
+
const {
|
|
7062
|
+
initialState,
|
|
7063
|
+
sync,
|
|
7064
|
+
inspector,
|
|
7065
|
+
theme,
|
|
7066
|
+
viewType,
|
|
7067
|
+
offlineStorageKey,
|
|
7068
|
+
multiplayerUrl,
|
|
7069
|
+
...managerOptions
|
|
7070
|
+
} = options ?? {};
|
|
7071
|
+
const appData = getAppData(
|
|
7072
|
+
initialState ?? null,
|
|
7073
|
+
managerOptions?.schema,
|
|
7074
|
+
{ overrideExistingState: managerOptions?.overrideExistingState }
|
|
7075
|
+
);
|
|
7076
|
+
noyaManagerSingleton = new NoyaManager4(
|
|
7077
|
+
appData.initialState,
|
|
7078
|
+
managerOptions
|
|
7079
|
+
);
|
|
7080
|
+
const resolvedSync = sync ?? getSyncAdapter({
|
|
7081
|
+
multiplayerUrl: multiplayerUrl ?? appData.multiplayerUrl,
|
|
7082
|
+
offlineStorageKey,
|
|
7083
|
+
debug: managerOptions?.debug
|
|
7084
|
+
});
|
|
7085
|
+
try {
|
|
7086
|
+
resolvedSync({ noyaManager: noyaManagerSingleton });
|
|
7087
|
+
} catch (error) {
|
|
7088
|
+
console.warn("Failed to activate sync", error);
|
|
7089
|
+
}
|
|
7090
|
+
const resolvedInspector = inspector ?? appData.inspector;
|
|
7091
|
+
const resolvedTheme = theme ?? appData.theme ?? "light";
|
|
7092
|
+
const resolvedViewType = viewType ?? appData.viewType ?? "editable";
|
|
7093
|
+
if (resolvedInspector) {
|
|
7094
|
+
const { root } = createStateInspectorRoot();
|
|
7095
|
+
root.render(
|
|
7096
|
+
/* @__PURE__ */ React16.createElement(
|
|
7097
|
+
StateInspector,
|
|
7098
|
+
{
|
|
7099
|
+
noyaManager: noyaManagerSingleton,
|
|
7100
|
+
colorScheme: resolvedInspector === true ? resolvedTheme : resolvedInspector.colorScheme,
|
|
7101
|
+
anchor: resolvedInspector === true ? "bottom right" : resolvedInspector.anchor
|
|
7102
|
+
}
|
|
7103
|
+
)
|
|
7104
|
+
);
|
|
7105
|
+
}
|
|
7106
|
+
noyaSingletonBindings = {
|
|
7107
|
+
sync: resolvedSync,
|
|
7108
|
+
inspector: resolvedInspector,
|
|
7109
|
+
theme: resolvedTheme,
|
|
7110
|
+
viewType: resolvedViewType
|
|
7111
|
+
};
|
|
7112
|
+
}
|
|
7113
|
+
function getNoyaManagerSingleton() {
|
|
7114
|
+
if (!noyaManagerSingleton || !noyaSingletonBindings) {
|
|
7115
|
+
throw new Error(
|
|
7116
|
+
"Noya has not been initialized. Call initializeNoya once before using Noya hooks."
|
|
7117
|
+
);
|
|
7118
|
+
}
|
|
7119
|
+
return noyaManagerSingleton;
|
|
7120
|
+
}
|
|
7121
|
+
function getNoyaSingletonBindings() {
|
|
7122
|
+
return noyaSingletonBindings;
|
|
7123
|
+
}
|
|
7124
|
+
function deleteNoyaSingleton() {
|
|
7125
|
+
noyaManagerSingleton = void 0;
|
|
7126
|
+
noyaSingletonBindings = void 0;
|
|
7127
|
+
}
|
|
7128
|
+
|
|
6947
7129
|
// src/NoyaStateContext.tsx
|
|
7130
|
+
function resourceToCreateParameters(resource) {
|
|
7131
|
+
switch (resource.type) {
|
|
7132
|
+
case "directory":
|
|
7133
|
+
return {
|
|
7134
|
+
path: resource.path,
|
|
7135
|
+
type: "directory"
|
|
7136
|
+
};
|
|
7137
|
+
case "asset":
|
|
7138
|
+
return {
|
|
7139
|
+
path: resource.path,
|
|
7140
|
+
type: "asset",
|
|
7141
|
+
assetId: resource.assetId,
|
|
7142
|
+
asset: resource.asset
|
|
7143
|
+
};
|
|
7144
|
+
case "file":
|
|
7145
|
+
return {
|
|
7146
|
+
path: resource.path,
|
|
7147
|
+
type: "file",
|
|
7148
|
+
fileId: resource.fileId
|
|
7149
|
+
};
|
|
7150
|
+
case "resource":
|
|
7151
|
+
return {
|
|
7152
|
+
path: resource.path,
|
|
7153
|
+
type: "resource",
|
|
7154
|
+
fileId: resource.fileId,
|
|
7155
|
+
resourceId: resource.resourceId
|
|
7156
|
+
};
|
|
7157
|
+
default:
|
|
7158
|
+
throw new Error(`Unknown resource type: ${resource.type}`);
|
|
7159
|
+
}
|
|
7160
|
+
}
|
|
7161
|
+
function buildCreateResourcePayload({
|
|
7162
|
+
addedResources,
|
|
7163
|
+
modifiedResources,
|
|
7164
|
+
newResourceMap,
|
|
7165
|
+
resourceMap
|
|
7166
|
+
}) {
|
|
7167
|
+
const toCreateParameters = resourceToCreateParameters;
|
|
7168
|
+
const resourcesById = new Map(
|
|
7169
|
+
Object.values(resourceMap).map((resource) => [resource.id, resource])
|
|
7170
|
+
);
|
|
7171
|
+
const payload = [
|
|
7172
|
+
...addedResources.map(toCreateParameters)
|
|
7173
|
+
];
|
|
7174
|
+
const handledModifiedResourceIds = [];
|
|
7175
|
+
const assetReplacements = modifiedResources.filter(
|
|
7176
|
+
(resource) => resource.assetId !== void 0 || resource.asset !== void 0
|
|
7177
|
+
).map((resource) => {
|
|
7178
|
+
const previousResource = resourcesById.get(resource.id);
|
|
7179
|
+
const path2 = resource.path ?? previousResource?.path;
|
|
7180
|
+
if (!path2) return void 0;
|
|
7181
|
+
const updated = newResourceMap[path2];
|
|
7182
|
+
if (!updated || updated.type !== "asset") return void 0;
|
|
7183
|
+
handledModifiedResourceIds.push(resource.id);
|
|
7184
|
+
return toCreateParameters(updated);
|
|
7185
|
+
}).filter(
|
|
7186
|
+
(resource) => resource !== void 0
|
|
7187
|
+
);
|
|
7188
|
+
const deduped = new Map(
|
|
7189
|
+
[...payload, ...assetReplacements].map((item) => [item.path, item])
|
|
7190
|
+
);
|
|
7191
|
+
return {
|
|
7192
|
+
payload: Array.from(deduped.values()),
|
|
7193
|
+
consumedModifiedResourceIds: [...new Set(handledModifiedResourceIds)]
|
|
7194
|
+
};
|
|
7195
|
+
}
|
|
6948
7196
|
var AnyNoyaStateContext = createContext(void 0);
|
|
6949
7197
|
function useAnyNoyaStateContext() {
|
|
6950
7198
|
const value = useContext(AnyNoyaStateContext);
|
|
6951
7199
|
if (!value) {
|
|
7200
|
+
const bindings = getNoyaSingletonBindings();
|
|
7201
|
+
if (bindings) {
|
|
7202
|
+
return {
|
|
7203
|
+
noyaManager: getNoyaManagerSingleton(),
|
|
7204
|
+
theme: bindings.theme,
|
|
7205
|
+
viewType: bindings.viewType
|
|
7206
|
+
};
|
|
7207
|
+
}
|
|
6952
7208
|
throw new Error(
|
|
6953
7209
|
"useNoyaStateContext must be used within a NoyaStateProvider"
|
|
6954
7210
|
);
|
|
@@ -6975,7 +7231,7 @@ function useAsset(id) {
|
|
|
6975
7231
|
const { noyaManager } = useAnyNoyaStateContext();
|
|
6976
7232
|
const observable = useMemo4(
|
|
6977
7233
|
() => noyaManager.assetManager.assets$.map(
|
|
6978
|
-
(assets) => assets.find((a) => a.id === id)
|
|
7234
|
+
(assets) => assets.find((a) => a.stableId === id) ?? assets.find((a) => a.id === id)
|
|
6979
7235
|
),
|
|
6980
7236
|
[noyaManager, id]
|
|
6981
7237
|
);
|
|
@@ -7055,9 +7311,9 @@ function usePipelineManager() {
|
|
|
7055
7311
|
const { noyaManager } = useAnyNoyaStateContext();
|
|
7056
7312
|
return noyaManager.pipelineManager;
|
|
7057
7313
|
}
|
|
7058
|
-
var ConnectedUsersContext = createContext(void 0);
|
|
7059
7314
|
function useConnectedUsersManager() {
|
|
7060
|
-
|
|
7315
|
+
const { noyaManager } = useAnyNoyaStateContext();
|
|
7316
|
+
return noyaManager.connectedUsersManager;
|
|
7061
7317
|
}
|
|
7062
7318
|
function useConnectedUsers() {
|
|
7063
7319
|
const connectedUsersManager = useConnectedUsersManager();
|
|
@@ -7078,9 +7334,9 @@ function useConnectedUser(userId) {
|
|
|
7078
7334
|
)
|
|
7079
7335
|
);
|
|
7080
7336
|
}
|
|
7081
|
-
var AnyEphemeralUserDataManagerContext = createContext(void 0);
|
|
7082
7337
|
function useAnyEphemeralUserData() {
|
|
7083
|
-
|
|
7338
|
+
const { noyaManager } = useAnyNoyaStateContext();
|
|
7339
|
+
return noyaManager.ephemeralUserDataManager;
|
|
7084
7340
|
}
|
|
7085
7341
|
function useCurrentUserId() {
|
|
7086
7342
|
const connectedUsersManager = useConnectedUsersManager();
|
|
@@ -7090,6 +7346,19 @@ function useIsProcessing() {
|
|
|
7090
7346
|
const { noyaManager } = useAnyNoyaStateContext();
|
|
7091
7347
|
return useObservable(noyaManager.isProcessing$);
|
|
7092
7348
|
}
|
|
7349
|
+
function useFileName() {
|
|
7350
|
+
const { noyaManager } = useAnyNoyaStateContext();
|
|
7351
|
+
return useObservable(noyaManager.filePropertyManager.optimisticValue$);
|
|
7352
|
+
}
|
|
7353
|
+
function useFilePropertyManager() {
|
|
7354
|
+
const { noyaManager } = useAnyNoyaStateContext();
|
|
7355
|
+
return noyaManager.filePropertyManager;
|
|
7356
|
+
}
|
|
7357
|
+
function useSetFileNameState() {
|
|
7358
|
+
const fileName = useFileName();
|
|
7359
|
+
const filePropertyManager = useFilePropertyManager();
|
|
7360
|
+
return [fileName, filePropertyManager.updateName];
|
|
7361
|
+
}
|
|
7093
7362
|
function useResourceManager() {
|
|
7094
7363
|
const { noyaManager } = useAnyNoyaStateContext();
|
|
7095
7364
|
return noyaManager.resourceManager;
|
|
@@ -7121,59 +7390,38 @@ function useResources({
|
|
|
7121
7390
|
async (action) => {
|
|
7122
7391
|
const newResourceMap = action instanceof Function ? action(resourceMap) : action;
|
|
7123
7392
|
const { addedResources, removedResources, modifiedResources } = diffResourceMaps(resourceMap, newResourceMap, "id");
|
|
7124
|
-
|
|
7125
|
-
|
|
7126
|
-
|
|
7127
|
-
|
|
7128
|
-
|
|
7129
|
-
|
|
7130
|
-
|
|
7131
|
-
|
|
7132
|
-
case "asset":
|
|
7133
|
-
return {
|
|
7134
|
-
path: resource.path,
|
|
7135
|
-
type: "asset",
|
|
7136
|
-
assetId: resource.assetId,
|
|
7137
|
-
asset: resource.asset
|
|
7138
|
-
};
|
|
7139
|
-
case "file":
|
|
7140
|
-
return {
|
|
7141
|
-
path: resource.path,
|
|
7142
|
-
type: "file",
|
|
7143
|
-
fileId: resource.fileId
|
|
7144
|
-
};
|
|
7145
|
-
case "resource":
|
|
7146
|
-
return {
|
|
7147
|
-
path: resource.path,
|
|
7148
|
-
type: "resource",
|
|
7149
|
-
fileId: resource.fileId,
|
|
7150
|
-
resourceId: resource.resourceId
|
|
7151
|
-
};
|
|
7152
|
-
default:
|
|
7153
|
-
throw new Error(
|
|
7154
|
-
`Unknown resource type: ${resource.type}`
|
|
7155
|
-
);
|
|
7156
|
-
}
|
|
7157
|
-
});
|
|
7158
|
-
await resourceManager.createResource(payload);
|
|
7393
|
+
const { payload: createPayload, consumedModifiedResourceIds } = buildCreateResourcePayload({
|
|
7394
|
+
addedResources,
|
|
7395
|
+
modifiedResources,
|
|
7396
|
+
newResourceMap,
|
|
7397
|
+
resourceMap
|
|
7398
|
+
});
|
|
7399
|
+
if (createPayload.length > 0) {
|
|
7400
|
+
await resourceManager.createResource(createPayload);
|
|
7159
7401
|
}
|
|
7160
|
-
|
|
7161
|
-
|
|
7162
|
-
|
|
7163
|
-
|
|
7402
|
+
const consumedModifiedResourceIdsSet = new Set(
|
|
7403
|
+
consumedModifiedResourceIds
|
|
7404
|
+
);
|
|
7405
|
+
const remainingModifiedResources = modifiedResources.filter(
|
|
7406
|
+
(resource) => !consumedModifiedResourceIdsSet.has(resource.id)
|
|
7407
|
+
);
|
|
7408
|
+
await resourceManager.deleteResource(
|
|
7409
|
+
removedResources.map((resource) => ({ id: resource.id }))
|
|
7410
|
+
);
|
|
7411
|
+
if (shouldDeleteAssets) {
|
|
7412
|
+
for (const resource of removedResources) {
|
|
7413
|
+
if (resource.type === "asset") {
|
|
7164
7414
|
await assetManager.delete(resource.assetId);
|
|
7165
|
-
} catch (error) {
|
|
7166
|
-
console.error("Failed to delete asset:", error);
|
|
7167
7415
|
}
|
|
7168
7416
|
}
|
|
7169
7417
|
}
|
|
7170
7418
|
await Promise.all(
|
|
7171
|
-
|
|
7419
|
+
remainingModifiedResources.map(
|
|
7172
7420
|
({ id, path: path2, assetId, asset }) => resourceManager.updateResource({
|
|
7173
7421
|
id,
|
|
7174
7422
|
path: path2,
|
|
7175
7423
|
assetId,
|
|
7176
|
-
asset
|
|
7424
|
+
...assetId ? {} : asset ? { asset } : {}
|
|
7177
7425
|
})
|
|
7178
7426
|
)
|
|
7179
7427
|
);
|
|
@@ -7220,41 +7468,25 @@ function createNoyaContext({
|
|
|
7220
7468
|
safeEval
|
|
7221
7469
|
}) {
|
|
7222
7470
|
const NoyaStateContext = AnyNoyaStateContext;
|
|
7223
|
-
const EphemeralUserDataManagerContext = AnyEphemeralUserDataManagerContext;
|
|
7224
7471
|
function NoyaContextProvider({
|
|
7225
7472
|
children,
|
|
7226
7473
|
contextValue
|
|
7227
7474
|
}) {
|
|
7228
|
-
return /* @__PURE__ */
|
|
7229
|
-
ConnectedUsersContext.Provider,
|
|
7230
|
-
{
|
|
7231
|
-
value: contextValue.noyaManager.connectedUsersManager
|
|
7232
|
-
},
|
|
7233
|
-
/* @__PURE__ */ React16.createElement(
|
|
7234
|
-
EphemeralUserDataManagerContext.Provider,
|
|
7235
|
-
{
|
|
7236
|
-
value: contextValue.noyaManager.ephemeralUserDataManager
|
|
7237
|
-
},
|
|
7238
|
-
children
|
|
7239
|
-
)
|
|
7240
|
-
));
|
|
7475
|
+
return /* @__PURE__ */ React17.createElement(AnyNoyaStateContext.Provider, { value: contextValue }, children);
|
|
7241
7476
|
}
|
|
7242
7477
|
function NoyaStateProvider({
|
|
7243
7478
|
children,
|
|
7244
7479
|
initialState,
|
|
7245
7480
|
...options
|
|
7246
7481
|
}) {
|
|
7247
|
-
const [, , { noyaManager, theme, viewType }] =
|
|
7248
|
-
|
|
7249
|
-
|
|
7250
|
-
|
|
7251
|
-
|
|
7252
|
-
|
|
7253
|
-
|
|
7254
|
-
|
|
7255
|
-
...options
|
|
7256
|
-
}
|
|
7257
|
-
);
|
|
7482
|
+
const [, , { noyaManager, theme, viewType }] = useNoyaStateInternal(initialState, {
|
|
7483
|
+
schema,
|
|
7484
|
+
mergeHistoryEntries,
|
|
7485
|
+
outputTransforms,
|
|
7486
|
+
inputs,
|
|
7487
|
+
safeEval,
|
|
7488
|
+
...options
|
|
7489
|
+
});
|
|
7258
7490
|
const contextValue = useMemo4(
|
|
7259
7491
|
() => ({
|
|
7260
7492
|
noyaManager,
|
|
@@ -7263,7 +7495,7 @@ function createNoyaContext({
|
|
|
7263
7495
|
}),
|
|
7264
7496
|
[noyaManager, theme, viewType]
|
|
7265
7497
|
);
|
|
7266
|
-
return /* @__PURE__ */
|
|
7498
|
+
return /* @__PURE__ */ React17.createElement(NoyaContextProvider, { contextValue }, options.fallback !== void 0 ? /* @__PURE__ */ React17.createElement(FallbackUntilInitialized, { fallback: options.fallback }, children) : children);
|
|
7267
7499
|
}
|
|
7268
7500
|
function useValue(path2, options) {
|
|
7269
7501
|
const { noyaManager } = useAnyNoyaStateContext();
|
|
@@ -7305,13 +7537,8 @@ function createNoyaContext({
|
|
|
7305
7537
|
return noyaManager.multiplayerStateManager;
|
|
7306
7538
|
}
|
|
7307
7539
|
function useEphemeralUserDataManager() {
|
|
7308
|
-
const
|
|
7309
|
-
|
|
7310
|
-
throw new Error(
|
|
7311
|
-
"useEphemeralUserData must be used within a NoyaStateProvider"
|
|
7312
|
-
);
|
|
7313
|
-
}
|
|
7314
|
-
return ephemeralUserData;
|
|
7540
|
+
const { noyaManager } = useAnyNoyaStateContext();
|
|
7541
|
+
return noyaManager.ephemeralUserDataManager;
|
|
7315
7542
|
}
|
|
7316
7543
|
function useNoyaManager() {
|
|
7317
7544
|
return useAnyNoyaStateContext().noyaManager;
|
|
@@ -7393,7 +7620,7 @@ function useCallableAITools() {
|
|
|
7393
7620
|
// src/components/UserPointersOverlay.tsx
|
|
7394
7621
|
import { Observable as Observable2 } from "@noya-app/observable";
|
|
7395
7622
|
import { memoGeneric as memoGeneric2 } from "@noya-app/react-utils";
|
|
7396
|
-
import
|
|
7623
|
+
import React18, { useEffect as useEffect6, useMemo as useMemo5, useState as useState5 } from "react";
|
|
7397
7624
|
function shouldShow(hideAfter, updatedAt) {
|
|
7398
7625
|
return !!updatedAt && Date.now() - updatedAt < hideAfter;
|
|
7399
7626
|
}
|
|
@@ -7436,9 +7663,9 @@ var UserPointersOverlay = memoGeneric2(function UserPointers({
|
|
|
7436
7663
|
}) {
|
|
7437
7664
|
const currentUserId = useObservable(ephemeralUserDataManager.currentUserId$);
|
|
7438
7665
|
const connectedUsers = useObservable(connectedUsersManager.connectedUsers$);
|
|
7439
|
-
return /* @__PURE__ */
|
|
7666
|
+
return /* @__PURE__ */ React18.createElement(React18.Fragment, null, connectedUsers.map((user) => {
|
|
7440
7667
|
if (user.id === currentUserId) return null;
|
|
7441
|
-
return /* @__PURE__ */
|
|
7668
|
+
return /* @__PURE__ */ React18.createElement(
|
|
7442
7669
|
UserPointerInternal,
|
|
7443
7670
|
{
|
|
7444
7671
|
key: user.id,
|
|
@@ -7531,24 +7758,30 @@ var WebSocketConnection = class {
|
|
|
7531
7758
|
}
|
|
7532
7759
|
};
|
|
7533
7760
|
export {
|
|
7534
|
-
AnyEphemeralUserDataManagerContext,
|
|
7535
7761
|
AnyNoyaStateContext,
|
|
7536
|
-
ConnectedUsersContext,
|
|
7537
7762
|
FallbackUntilInitialized,
|
|
7538
7763
|
StateInspector,
|
|
7539
7764
|
UserPointersOverlay,
|
|
7540
7765
|
WebSocketConnection,
|
|
7766
|
+
buildCreateResourcePayload,
|
|
7541
7767
|
createDefaultAppData,
|
|
7542
7768
|
createNoyaContext,
|
|
7769
|
+
createStateInspectorRoot,
|
|
7543
7770
|
decodeAll,
|
|
7771
|
+
deleteNoyaSingleton,
|
|
7544
7772
|
encodeAll,
|
|
7545
7773
|
enforceSchema,
|
|
7546
7774
|
exportAll,
|
|
7547
7775
|
fetchAssetMap,
|
|
7548
7776
|
getAppData,
|
|
7777
|
+
getNoyaManagerSingleton,
|
|
7778
|
+
getNoyaSingletonBindings,
|
|
7779
|
+
getSyncAdapter,
|
|
7549
7780
|
importAll,
|
|
7781
|
+
initializeNoyaSingleton,
|
|
7550
7782
|
parseAppDataParameter,
|
|
7551
7783
|
replaceDeep,
|
|
7784
|
+
resourceToCreateParameters,
|
|
7552
7785
|
resourceToMediaItem,
|
|
7553
7786
|
useAIManager,
|
|
7554
7787
|
useActivityEvents,
|
|
@@ -7559,12 +7792,15 @@ export {
|
|
|
7559
7792
|
useAsset,
|
|
7560
7793
|
useAssetManager,
|
|
7561
7794
|
useAssets,
|
|
7795
|
+
useBindNoyaManager,
|
|
7562
7796
|
useCallableAITools,
|
|
7563
7797
|
useColorScheme,
|
|
7564
7798
|
useConnectedUser,
|
|
7565
7799
|
useConnectedUsers,
|
|
7566
7800
|
useConnectedUsersManager,
|
|
7567
7801
|
useCurrentUserId,
|
|
7802
|
+
useFileName,
|
|
7803
|
+
useFilePropertyManager,
|
|
7568
7804
|
useIOManager,
|
|
7569
7805
|
useInputs,
|
|
7570
7806
|
useIsInitialized,
|
|
@@ -7572,7 +7808,7 @@ export {
|
|
|
7572
7808
|
useManagedHistory,
|
|
7573
7809
|
useManagedState,
|
|
7574
7810
|
useMultiplayerState,
|
|
7575
|
-
|
|
7811
|
+
useNoyaStateInternal,
|
|
7576
7812
|
useObservable,
|
|
7577
7813
|
useOutputTransforms,
|
|
7578
7814
|
usePipelineManager,
|
|
@@ -7583,8 +7819,8 @@ export {
|
|
|
7583
7819
|
useSecret,
|
|
7584
7820
|
useSecretManager,
|
|
7585
7821
|
useSecrets,
|
|
7822
|
+
useSetFileNameState,
|
|
7586
7823
|
useStateInspector,
|
|
7587
|
-
useSyncStateManager,
|
|
7588
7824
|
useViewType
|
|
7589
7825
|
};
|
|
7590
7826
|
//# sourceMappingURL=index.mjs.map
|