@xnetjs/react 2.3.0 → 2.5.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.d.ts +52 -1
- package/dist/index.js +122 -37
- package/package.json +10 -10
package/dist/index.d.ts
CHANGED
|
@@ -710,6 +710,57 @@ interface UseGridDatabaseResult {
|
|
|
710
710
|
}
|
|
711
711
|
declare function useGridDatabase(databaseId: string, options?: UseGridDatabaseOptions): UseGridDatabaseResult;
|
|
712
712
|
|
|
713
|
+
/**
|
|
714
|
+
* The entangle bus (exploration 0346, Phase 3) — page-scoped hover/select
|
|
715
|
+
* co-presence between frames.
|
|
716
|
+
*
|
|
717
|
+
* Frames on one page share a bus: hovering a row in a database frame
|
|
718
|
+
* lights the same node's pin in a map frame and its wikilink in the
|
|
719
|
+
* prose (Embark's "Entangler"). Cheap by construction: per-node
|
|
720
|
+
* subscriptions through useSyncExternalStore, so only the components
|
|
721
|
+
* whose highlight state actually changes re-render.
|
|
722
|
+
*
|
|
723
|
+
* Absent a provider every hook degrades to a no-op, so views adopt the
|
|
724
|
+
* bus unconditionally and stay correct on bus-less surfaces.
|
|
725
|
+
*/
|
|
726
|
+
|
|
727
|
+
declare class EntangleBus {
|
|
728
|
+
private hovered;
|
|
729
|
+
private selected;
|
|
730
|
+
private listeners;
|
|
731
|
+
setHovered(nodeId: string, on: boolean): void;
|
|
732
|
+
setSelected(nodeIds: readonly string[]): void;
|
|
733
|
+
isHovered(nodeId: string): boolean;
|
|
734
|
+
isSelected(nodeId: string): boolean;
|
|
735
|
+
/** All currently highlighted ids (hovered ∪ selected) — for canvas
|
|
736
|
+
* renderers (map layers) that filter rather than subscribe per id. */
|
|
737
|
+
snapshotHighlighted(): string[];
|
|
738
|
+
subscribe: (listener: () => void) => (() => void);
|
|
739
|
+
private notify;
|
|
740
|
+
}
|
|
741
|
+
/** One bus per page surface — mount around the page's frames. */
|
|
742
|
+
declare function EntangleProvider({ children }: {
|
|
743
|
+
children: ReactNode;
|
|
744
|
+
}): JSX.Element;
|
|
745
|
+
/** The surrounding bus, or null on bus-less surfaces. */
|
|
746
|
+
declare function useEntangleBus(): EntangleBus | null;
|
|
747
|
+
/**
|
|
748
|
+
* Whether this node is entangle-highlighted (hovered or selected in a
|
|
749
|
+
* sibling frame). Subscribes per node id — only affected rows/pins
|
|
750
|
+
* re-render on hover changes.
|
|
751
|
+
*/
|
|
752
|
+
declare function useEntangledHighlight(nodeId: string | null | undefined): boolean;
|
|
753
|
+
/** Publish hover on/off for a node id (no-op without a bus). */
|
|
754
|
+
declare function usePublishEntangleHover(): (nodeId: string, on: boolean) => void;
|
|
755
|
+
/**
|
|
756
|
+
* Convenience bind: spread onto a row/card/chip element to publish its
|
|
757
|
+
* node's hover state.
|
|
758
|
+
*/
|
|
759
|
+
declare function useEntangleBind(nodeId: string | null | undefined): {
|
|
760
|
+
onMouseEnter?: () => void;
|
|
761
|
+
onMouseLeave?: () => void;
|
|
762
|
+
};
|
|
763
|
+
|
|
713
764
|
/**
|
|
714
765
|
* useTimeMachine — React binding for the Time Machine (exploration 0329 P1).
|
|
715
766
|
*
|
|
@@ -989,4 +1040,4 @@ declare function flattenTaskTree(items: TaskTreeItem[], depth?: number): Rendera
|
|
|
989
1040
|
declare function formatTaskDueDate(timestamp: number | undefined): string | null;
|
|
990
1041
|
declare function isTaskOverdue(timestamp: number | undefined, completed: boolean): boolean;
|
|
991
1042
|
|
|
992
|
-
export { type AddRowOptions, type CanvasTaskInput, type CheckoutOptions, type DraftReview, type DraftReviewCard, type DraftReviewMember, FlatNode, type GridFieldModel, type GridOptionModel, type GridRowModel, type GridViewConfigPatch, type GridViewModel, type PresenceAwareness, type PresencePeer, QueryFilter, type RenderableTaskRow, type SavedViewCanvasProjectionNode, type SavedViewDateBrushSelection, type SavedViewDateBucketFieldSummary, type SavedViewDateBucketInterval, type SavedViewDateBucketSummary, type SavedViewFacetSelection, type SavedViewFacetSummary, type SavedViewFacetValueSummary, type SavedViewFeedEnrichmentAdapter, type SavedViewFeedEnrichmentEntry, type SavedViewInspectorItem, type SavedViewInspectorItemKind, type SavedViewLensDraft, type SavedViewPresentationMode, type SavedViewPrivacyChip, type SavedViewPrivacyChipTone, type SavedViewPrivacySummary, type SavedViewQueryOverride, type SavedViewQueryResult, SavedViewResultTable, type SavedViewResultTableProps, type SavedViewRowInspectorModel, SavedViewRunner, type SavedViewRunnerProps, type SavedViewSchemaRegistry, type SavedViewSortDirection, type SavedViewVisualCanvasProjectionRequest, SavedViewVisualFeed, type SavedViewVisualLayoutId, type SavedViewVisualLayoutOption, type SavedViewVisualPreviewCreator, type SavedViewVisualPreviewKind, type SavedViewVisualPreviewModel, type SavedViewVisualPreviewPrivacy, type SavedViewVisualPreviewRelationship, type SavedViewVisualTimelineBucket, type SavedViewVisualWorkspaceLayout, TaskProjectionInput, TaskTreeItem, type UseBillingResult, type UseCanCreateResult, type UseCanvasTaskSyncOptions, type UseCanvasTaskSyncResult, type UseDraftResult, type UseEffectiveSchemaResult, type UseGlobalUndoResult, type UseGridDatabaseOptions, type UseGridDatabaseResult, type UsePresenceOptions, type UsePresenceResult, type UseSavedViewOptions, type UseSavedViewResult, UseTaskProjectionSyncResult, type UseTimeMachineOptions, type UseTimeMachineResult, createSavedViewCanvasProjectionNodes, createSavedViewLensDraft, createSavedViewVisualCanvasProjectionRequest, createSavedViewVisualPreviewFingerprint, deriveCachedSavedViewVisualPreviews, deriveSavedViewColumns, deriveSavedViewDateBucketSummaries, deriveSavedViewFacetSummaries, deriveSavedViewPrivacyChips, deriveSavedViewRowInspector, deriveSavedViewTimelineBuckets, deriveSavedViewVisualPreview, deriveSavedViewVisualPreviews, filterSavedViewRowsByDateBrush, filterSavedViewRowsByFacets, flattenTaskTree, formatSavedViewCellValue, formatTaskDueDate, getSavedViewSensitiveResultWarning, hasSavedViewVisualPreviewSensitiveData, isSavedViewVisualPreviewEmbeddable, isTaskOverdue, mergeSavedViewFeedEnrichment, savedViewVisualPreviewIsSelfActor, useBilling, useCanCreate, useCanvasTaskSync, useDraft, useEffectiveSchema, useGlobalUndo, useGridDatabase, usePresence, useSavedView, useTimeMachine };
|
|
1043
|
+
export { type AddRowOptions, type CanvasTaskInput, type CheckoutOptions, type DraftReview, type DraftReviewCard, type DraftReviewMember, EntangleBus, EntangleProvider, FlatNode, type GridFieldModel, type GridOptionModel, type GridRowModel, type GridViewConfigPatch, type GridViewModel, type PresenceAwareness, type PresencePeer, QueryFilter, type RenderableTaskRow, type SavedViewCanvasProjectionNode, type SavedViewDateBrushSelection, type SavedViewDateBucketFieldSummary, type SavedViewDateBucketInterval, type SavedViewDateBucketSummary, type SavedViewFacetSelection, type SavedViewFacetSummary, type SavedViewFacetValueSummary, type SavedViewFeedEnrichmentAdapter, type SavedViewFeedEnrichmentEntry, type SavedViewInspectorItem, type SavedViewInspectorItemKind, type SavedViewLensDraft, type SavedViewPresentationMode, type SavedViewPrivacyChip, type SavedViewPrivacyChipTone, type SavedViewPrivacySummary, type SavedViewQueryOverride, type SavedViewQueryResult, SavedViewResultTable, type SavedViewResultTableProps, type SavedViewRowInspectorModel, SavedViewRunner, type SavedViewRunnerProps, type SavedViewSchemaRegistry, type SavedViewSortDirection, type SavedViewVisualCanvasProjectionRequest, SavedViewVisualFeed, type SavedViewVisualLayoutId, type SavedViewVisualLayoutOption, type SavedViewVisualPreviewCreator, type SavedViewVisualPreviewKind, type SavedViewVisualPreviewModel, type SavedViewVisualPreviewPrivacy, type SavedViewVisualPreviewRelationship, type SavedViewVisualTimelineBucket, type SavedViewVisualWorkspaceLayout, TaskProjectionInput, TaskTreeItem, type UseBillingResult, type UseCanCreateResult, type UseCanvasTaskSyncOptions, type UseCanvasTaskSyncResult, type UseDraftResult, type UseEffectiveSchemaResult, type UseGlobalUndoResult, type UseGridDatabaseOptions, type UseGridDatabaseResult, type UsePresenceOptions, type UsePresenceResult, type UseSavedViewOptions, type UseSavedViewResult, UseTaskProjectionSyncResult, type UseTimeMachineOptions, type UseTimeMachineResult, createSavedViewCanvasProjectionNodes, createSavedViewLensDraft, createSavedViewVisualCanvasProjectionRequest, createSavedViewVisualPreviewFingerprint, deriveCachedSavedViewVisualPreviews, deriveSavedViewColumns, deriveSavedViewDateBucketSummaries, deriveSavedViewFacetSummaries, deriveSavedViewPrivacyChips, deriveSavedViewRowInspector, deriveSavedViewTimelineBuckets, deriveSavedViewVisualPreview, deriveSavedViewVisualPreviews, filterSavedViewRowsByDateBrush, filterSavedViewRowsByFacets, flattenTaskTree, formatSavedViewCellValue, formatTaskDueDate, getSavedViewSensitiveResultWarning, hasSavedViewVisualPreviewSensitiveData, isSavedViewVisualPreviewEmbeddable, isTaskOverdue, mergeSavedViewFeedEnrichment, savedViewVisualPreviewIsSelfActor, useBilling, useCanCreate, useCanvasTaskSync, useDraft, useEffectiveSchema, useEntangleBind, useEntangleBus, useEntangledHighlight, useGlobalUndo, useGridDatabase, usePresence, usePublishEntangleHover, useSavedView, useTimeMachine };
|
package/dist/index.js
CHANGED
|
@@ -5001,6 +5001,85 @@ function useGridDatabase(databaseId, options = {}) {
|
|
|
5001
5001
|
};
|
|
5002
5002
|
}
|
|
5003
5003
|
|
|
5004
|
+
// src/hooks/useEntangle.tsx
|
|
5005
|
+
import {
|
|
5006
|
+
createContext,
|
|
5007
|
+
useCallback as useCallback4,
|
|
5008
|
+
useContext,
|
|
5009
|
+
useMemo as useMemo6,
|
|
5010
|
+
useSyncExternalStore
|
|
5011
|
+
} from "react";
|
|
5012
|
+
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
5013
|
+
var EntangleBus = class {
|
|
5014
|
+
hovered = /* @__PURE__ */ new Set();
|
|
5015
|
+
selected = /* @__PURE__ */ new Set();
|
|
5016
|
+
listeners = /* @__PURE__ */ new Set();
|
|
5017
|
+
setHovered(nodeId, on) {
|
|
5018
|
+
if (on === this.hovered.has(nodeId)) return;
|
|
5019
|
+
if (on) this.hovered.add(nodeId);
|
|
5020
|
+
else this.hovered.delete(nodeId);
|
|
5021
|
+
this.notify();
|
|
5022
|
+
}
|
|
5023
|
+
setSelected(nodeIds) {
|
|
5024
|
+
this.selected = new Set(nodeIds);
|
|
5025
|
+
this.notify();
|
|
5026
|
+
}
|
|
5027
|
+
isHovered(nodeId) {
|
|
5028
|
+
return this.hovered.has(nodeId);
|
|
5029
|
+
}
|
|
5030
|
+
isSelected(nodeId) {
|
|
5031
|
+
return this.selected.has(nodeId);
|
|
5032
|
+
}
|
|
5033
|
+
/** All currently highlighted ids (hovered ∪ selected) — for canvas
|
|
5034
|
+
* renderers (map layers) that filter rather than subscribe per id. */
|
|
5035
|
+
snapshotHighlighted() {
|
|
5036
|
+
return [.../* @__PURE__ */ new Set([...this.hovered, ...this.selected])];
|
|
5037
|
+
}
|
|
5038
|
+
subscribe = (listener) => {
|
|
5039
|
+
this.listeners.add(listener);
|
|
5040
|
+
return () => this.listeners.delete(listener);
|
|
5041
|
+
};
|
|
5042
|
+
notify() {
|
|
5043
|
+
for (const listener of this.listeners) listener();
|
|
5044
|
+
}
|
|
5045
|
+
};
|
|
5046
|
+
var EntangleContext = createContext(null);
|
|
5047
|
+
function EntangleProvider({ children }) {
|
|
5048
|
+
const bus = useMemo6(() => new EntangleBus(), []);
|
|
5049
|
+
return /* @__PURE__ */ jsx3(EntangleContext.Provider, { value: bus, children });
|
|
5050
|
+
}
|
|
5051
|
+
function useEntangleBus() {
|
|
5052
|
+
return useContext(EntangleContext);
|
|
5053
|
+
}
|
|
5054
|
+
var noopSubscribe = () => () => {
|
|
5055
|
+
};
|
|
5056
|
+
function useEntangledHighlight(nodeId) {
|
|
5057
|
+
const bus = useContext(EntangleContext);
|
|
5058
|
+
return useSyncExternalStore(
|
|
5059
|
+
bus ? bus.subscribe : noopSubscribe,
|
|
5060
|
+
() => bus && nodeId ? bus.isHovered(nodeId) || bus.isSelected(nodeId) : false
|
|
5061
|
+
);
|
|
5062
|
+
}
|
|
5063
|
+
function usePublishEntangleHover() {
|
|
5064
|
+
const bus = useContext(EntangleContext);
|
|
5065
|
+
return useCallback4(
|
|
5066
|
+
(nodeId, on) => {
|
|
5067
|
+
bus?.setHovered(nodeId, on);
|
|
5068
|
+
},
|
|
5069
|
+
[bus]
|
|
5070
|
+
);
|
|
5071
|
+
}
|
|
5072
|
+
function useEntangleBind(nodeId) {
|
|
5073
|
+
const bus = useContext(EntangleContext);
|
|
5074
|
+
return useMemo6(() => {
|
|
5075
|
+
if (!bus || !nodeId) return {};
|
|
5076
|
+
return {
|
|
5077
|
+
onMouseEnter: () => bus.setHovered(nodeId, true),
|
|
5078
|
+
onMouseLeave: () => bus.setHovered(nodeId, false)
|
|
5079
|
+
};
|
|
5080
|
+
}, [bus, nodeId]);
|
|
5081
|
+
}
|
|
5082
|
+
|
|
5004
5083
|
// src/hooks/useTimeMachine.ts
|
|
5005
5084
|
import { CHECKPOINT_SCHEMA_IRI } from "@xnetjs/data";
|
|
5006
5085
|
import {
|
|
@@ -5013,11 +5092,11 @@ import {
|
|
|
5013
5092
|
listCheckpoints,
|
|
5014
5093
|
restoreToFrontier
|
|
5015
5094
|
} from "@xnetjs/history";
|
|
5016
|
-
import { useCallback as
|
|
5095
|
+
import { useCallback as useCallback5, useEffect as useEffect7, useMemo as useMemo7, useRef as useRef5, useState as useState7 } from "react";
|
|
5017
5096
|
function useTimeMachine(nodeId, options) {
|
|
5018
5097
|
const { store, isReady } = useNodeStore();
|
|
5019
5098
|
const memberKey = options?.memberIds?.join(",") ?? "";
|
|
5020
|
-
const members =
|
|
5099
|
+
const members = useMemo7(() => {
|
|
5021
5100
|
if (!nodeId) return [];
|
|
5022
5101
|
const extra = options?.memberIds ?? [];
|
|
5023
5102
|
return [nodeId, ...extra.filter((id) => id !== nodeId)];
|
|
@@ -5034,7 +5113,7 @@ function useTimeMachine(nodeId, options) {
|
|
|
5034
5113
|
const [preview, setPreview] = useState7(null);
|
|
5035
5114
|
const [diffs, setDiffs] = useState7([]);
|
|
5036
5115
|
const engineRef = useRef5(null);
|
|
5037
|
-
const getEngines =
|
|
5116
|
+
const getEngines = useCallback5(() => {
|
|
5038
5117
|
if (!store) return null;
|
|
5039
5118
|
const storage = store.getStorageAdapter();
|
|
5040
5119
|
if (!storage) return null;
|
|
@@ -5048,7 +5127,7 @@ function useTimeMachine(nodeId, options) {
|
|
|
5048
5127
|
}
|
|
5049
5128
|
return engineRef.current;
|
|
5050
5129
|
}, [store]);
|
|
5051
|
-
const reload =
|
|
5130
|
+
const reload = useCallback5(async () => {
|
|
5052
5131
|
if (!nodeId || !isReady || !store) return;
|
|
5053
5132
|
const engines = getEngines();
|
|
5054
5133
|
if (!engines) return;
|
|
@@ -5132,7 +5211,7 @@ function useTimeMachine(nodeId, options) {
|
|
|
5132
5211
|
cancelled = true;
|
|
5133
5212
|
};
|
|
5134
5213
|
}, [nodeId, timeline, position, getEngines]);
|
|
5135
|
-
const setPosition =
|
|
5214
|
+
const setPosition = useCallback5(
|
|
5136
5215
|
(index) => {
|
|
5137
5216
|
const max = timeline.length - 1;
|
|
5138
5217
|
const clamped = Math.max(0, Math.min(index, max));
|
|
@@ -5140,10 +5219,10 @@ function useTimeMachine(nodeId, options) {
|
|
|
5140
5219
|
},
|
|
5141
5220
|
[timeline.length]
|
|
5142
5221
|
);
|
|
5143
|
-
const stepBack =
|
|
5144
|
-
const stepForward =
|
|
5145
|
-
const goToLatest =
|
|
5146
|
-
const createNamedVersion =
|
|
5222
|
+
const stepBack = useCallback5(() => setPosition(position - 1), [setPosition, position]);
|
|
5223
|
+
const stepForward = useCallback5(() => setPosition(position + 1), [setPosition, position]);
|
|
5224
|
+
const goToLatest = useCallback5(() => setRawPosition(null), []);
|
|
5225
|
+
const createNamedVersion = useCallback5(
|
|
5147
5226
|
async (name, note) => {
|
|
5148
5227
|
if (!nodeId || !store) return null;
|
|
5149
5228
|
const engines = getEngines();
|
|
@@ -5164,7 +5243,7 @@ function useTimeMachine(nodeId, options) {
|
|
|
5164
5243
|
},
|
|
5165
5244
|
[nodeId, store, members, getEngines, reload]
|
|
5166
5245
|
);
|
|
5167
|
-
const positionOfCheckpoint =
|
|
5246
|
+
const positionOfCheckpoint = useCallback5(
|
|
5168
5247
|
(checkpoint) => {
|
|
5169
5248
|
const frontier = checkpoint.properties.frontier;
|
|
5170
5249
|
if (!frontier) return null;
|
|
@@ -5179,7 +5258,7 @@ function useTimeMachine(nodeId, options) {
|
|
|
5179
5258
|
},
|
|
5180
5259
|
[timeline]
|
|
5181
5260
|
);
|
|
5182
|
-
const frontierAt =
|
|
5261
|
+
const frontierAt = useCallback5(
|
|
5183
5262
|
(index) => {
|
|
5184
5263
|
const scope = getEngines()?.scope;
|
|
5185
5264
|
if (!scope) return {};
|
|
@@ -5187,7 +5266,7 @@ function useTimeMachine(nodeId, options) {
|
|
|
5187
5266
|
},
|
|
5188
5267
|
[getEngines, timeline]
|
|
5189
5268
|
);
|
|
5190
|
-
const restore =
|
|
5269
|
+
const restore = useCallback5(async () => {
|
|
5191
5270
|
if (!nodeId || !store || timeline.length === 0) return null;
|
|
5192
5271
|
const engines = getEngines();
|
|
5193
5272
|
if (!engines) return null;
|
|
@@ -5242,7 +5321,7 @@ import {
|
|
|
5242
5321
|
refreshDraftFromMain,
|
|
5243
5322
|
threeWayPropertyMerge
|
|
5244
5323
|
} from "@xnetjs/history";
|
|
5245
|
-
import { useCallback as
|
|
5324
|
+
import { useCallback as useCallback6, useEffect as useEffect8, useRef as useRef6, useState as useState8 } from "react";
|
|
5246
5325
|
var baseIRI = (schemaId) => schemaId.split("@")[0];
|
|
5247
5326
|
async function resolveMembers(store, hostId) {
|
|
5248
5327
|
const members = [hostId];
|
|
@@ -5269,7 +5348,7 @@ function useDraft(hostId) {
|
|
|
5269
5348
|
const [loading, setLoading] = useState8(false);
|
|
5270
5349
|
const [error, setError] = useState8(null);
|
|
5271
5350
|
const engineRef = useRef6(null);
|
|
5272
|
-
const getEngines =
|
|
5351
|
+
const getEngines = useCallback6(() => {
|
|
5273
5352
|
if (!store) return null;
|
|
5274
5353
|
const storage = store.getStorageAdapter();
|
|
5275
5354
|
if (!storage) return null;
|
|
@@ -5285,7 +5364,7 @@ function useDraft(hostId) {
|
|
|
5285
5364
|
return engineRef.current;
|
|
5286
5365
|
}, [store]);
|
|
5287
5366
|
const draftIdsRef = useRef6(/* @__PURE__ */ new Set());
|
|
5288
|
-
const reload =
|
|
5367
|
+
const reload = useCallback6(async () => {
|
|
5289
5368
|
if (!hostId || !isReady || !store) return;
|
|
5290
5369
|
setLoading(true);
|
|
5291
5370
|
setError(null);
|
|
@@ -5324,7 +5403,7 @@ function useDraft(hostId) {
|
|
|
5324
5403
|
unsubOverlay();
|
|
5325
5404
|
};
|
|
5326
5405
|
}, [store, hostId, reload]);
|
|
5327
|
-
const checkout =
|
|
5406
|
+
const checkout = useCallback6(
|
|
5328
5407
|
async (draftId) => {
|
|
5329
5408
|
if (!hostId || !store) return false;
|
|
5330
5409
|
const engines = getEngines();
|
|
@@ -5358,11 +5437,11 @@ function useDraft(hostId) {
|
|
|
5358
5437
|
},
|
|
5359
5438
|
[hostId, store, getEngines, reload]
|
|
5360
5439
|
);
|
|
5361
|
-
const returnToMain =
|
|
5440
|
+
const returnToMain = useCallback6(() => {
|
|
5362
5441
|
if (!store) return;
|
|
5363
5442
|
store.setCheckedOutDraft(null);
|
|
5364
5443
|
}, [store]);
|
|
5365
|
-
const createDraft =
|
|
5444
|
+
const createDraft = useCallback6(
|
|
5366
5445
|
async (name) => {
|
|
5367
5446
|
if (!hostId || !store) return null;
|
|
5368
5447
|
try {
|
|
@@ -5376,7 +5455,7 @@ function useDraft(hostId) {
|
|
|
5376
5455
|
},
|
|
5377
5456
|
[hostId, store, checkout]
|
|
5378
5457
|
);
|
|
5379
|
-
const discard =
|
|
5458
|
+
const discard = useCallback6(
|
|
5380
5459
|
async (draftId) => {
|
|
5381
5460
|
if (!store) return false;
|
|
5382
5461
|
const engines = getEngines();
|
|
@@ -5395,7 +5474,7 @@ function useDraft(hostId) {
|
|
|
5395
5474
|
},
|
|
5396
5475
|
[store, getEngines, reload]
|
|
5397
5476
|
);
|
|
5398
|
-
const merge =
|
|
5477
|
+
const merge = useCallback6(
|
|
5399
5478
|
async (draftId) => {
|
|
5400
5479
|
if (!store) return null;
|
|
5401
5480
|
const engines = getEngines();
|
|
@@ -5414,7 +5493,7 @@ function useDraft(hostId) {
|
|
|
5414
5493
|
},
|
|
5415
5494
|
[store, getEngines, reload]
|
|
5416
5495
|
);
|
|
5417
|
-
const refresh =
|
|
5496
|
+
const refresh = useCallback6(
|
|
5418
5497
|
async (draftId) => {
|
|
5419
5498
|
if (!store) return null;
|
|
5420
5499
|
const engines = getEngines();
|
|
@@ -5430,7 +5509,7 @@ function useDraft(hostId) {
|
|
|
5430
5509
|
},
|
|
5431
5510
|
[store, getEngines, reload]
|
|
5432
5511
|
);
|
|
5433
|
-
const setReviewRequested =
|
|
5512
|
+
const setReviewRequested = useCallback6(
|
|
5434
5513
|
async (draftId, requested) => {
|
|
5435
5514
|
if (!store) return;
|
|
5436
5515
|
try {
|
|
@@ -5441,7 +5520,7 @@ function useDraft(hostId) {
|
|
|
5441
5520
|
},
|
|
5442
5521
|
[store]
|
|
5443
5522
|
);
|
|
5444
|
-
const computeReview =
|
|
5523
|
+
const computeReview = useCallback6(
|
|
5445
5524
|
async (draftId) => {
|
|
5446
5525
|
if (!store) return null;
|
|
5447
5526
|
const engines = getEngines();
|
|
@@ -5525,26 +5604,26 @@ function useDraft(hostId) {
|
|
|
5525
5604
|
}
|
|
5526
5605
|
|
|
5527
5606
|
// src/hooks/useGlobalUndo.ts
|
|
5528
|
-
import { useCallback as
|
|
5607
|
+
import { useCallback as useCallback7, useContext as useContext2, useEffect as useEffect9, useReducer } from "react";
|
|
5529
5608
|
function readUndoContext(ctx) {
|
|
5530
5609
|
if (!ctx) return { undoManager: null, nodeStore: null };
|
|
5531
5610
|
return { undoManager: ctx.undoManager, nodeStore: ctx.nodeStore };
|
|
5532
5611
|
}
|
|
5533
5612
|
function useGlobalUndo() {
|
|
5534
|
-
const ctx =
|
|
5613
|
+
const ctx = useContext2(XNetContext);
|
|
5535
5614
|
const { undoManager, nodeStore } = readUndoContext(ctx);
|
|
5536
5615
|
const [, bump] = useReducer((n) => n + 1, 0);
|
|
5537
5616
|
useEffect9(() => {
|
|
5538
5617
|
if (!nodeStore) return;
|
|
5539
5618
|
return nodeStore.subscribe(() => bump());
|
|
5540
5619
|
}, [nodeStore]);
|
|
5541
|
-
const undo =
|
|
5620
|
+
const undo = useCallback7(async () => {
|
|
5542
5621
|
if (!undoManager) return false;
|
|
5543
5622
|
const ok = await undoManager.undoLatest();
|
|
5544
5623
|
bump();
|
|
5545
5624
|
return ok;
|
|
5546
5625
|
}, [undoManager]);
|
|
5547
|
-
const redo =
|
|
5626
|
+
const redo = useCallback7(async () => {
|
|
5548
5627
|
if (!undoManager) return false;
|
|
5549
5628
|
const ok = await undoManager.redoLatest();
|
|
5550
5629
|
bump();
|
|
@@ -5559,7 +5638,7 @@ function useGlobalUndo() {
|
|
|
5559
5638
|
}
|
|
5560
5639
|
|
|
5561
5640
|
// src/hooks/useCanCreate.ts
|
|
5562
|
-
import { useEffect as useEffect10, useMemo as
|
|
5641
|
+
import { useEffect as useEffect10, useMemo as useMemo8, useRef as useRef7, useState as useState9 } from "react";
|
|
5563
5642
|
var INITIAL_STATE = {
|
|
5564
5643
|
canCreate: false,
|
|
5565
5644
|
loading: true,
|
|
@@ -5569,7 +5648,7 @@ function useCanCreate(schemaId, properties) {
|
|
|
5569
5648
|
const { store, isReady } = useNodeStore();
|
|
5570
5649
|
const [state, setState] = useState9(INITIAL_STATE);
|
|
5571
5650
|
const requestRef = useRef7(0);
|
|
5572
|
-
const propertiesKey =
|
|
5651
|
+
const propertiesKey = useMemo8(() => JSON.stringify(properties ?? {}), [properties]);
|
|
5573
5652
|
useEffect10(() => {
|
|
5574
5653
|
if (!store || !isReady) {
|
|
5575
5654
|
setState((prev) => ({ ...prev, loading: true }));
|
|
@@ -5639,7 +5718,7 @@ import {
|
|
|
5639
5718
|
} from "@xnetjs/runtime";
|
|
5640
5719
|
|
|
5641
5720
|
// src/hooks/useBilling.ts
|
|
5642
|
-
import { useCallback as
|
|
5721
|
+
import { useCallback as useCallback8, useContext as useContext3, useEffect as useEffect11, useMemo as useMemo9, useState as useState10 } from "react";
|
|
5643
5722
|
var toHttpUrl = (hubUrl) => {
|
|
5644
5723
|
try {
|
|
5645
5724
|
const url = new URL(hubUrl);
|
|
@@ -5675,21 +5754,21 @@ function deriveBilling(state) {
|
|
|
5675
5754
|
};
|
|
5676
5755
|
}
|
|
5677
5756
|
function useBilling() {
|
|
5678
|
-
const context =
|
|
5757
|
+
const context = useContext3(XNetContext);
|
|
5679
5758
|
const [state, setState] = useState10(null);
|
|
5680
5759
|
const [loading, setLoading] = useState10(
|
|
5681
5760
|
Boolean(context?.hubUrl || context?.billing?.apiBase)
|
|
5682
5761
|
);
|
|
5683
5762
|
const [error, setError] = useState10(null);
|
|
5684
|
-
const apiBase =
|
|
5763
|
+
const apiBase = useMemo9(() => {
|
|
5685
5764
|
if (context?.billing?.apiBase) return context.billing.apiBase.replace(/\/$/, "");
|
|
5686
5765
|
return context?.hubUrl ? toHttpUrl(context.hubUrl) : null;
|
|
5687
5766
|
}, [context?.billing?.apiBase, context?.hubUrl]);
|
|
5688
|
-
const authHeaders =
|
|
5767
|
+
const authHeaders = useCallback8(async () => {
|
|
5689
5768
|
const token = context?.getHubAuthToken ? await context.getHubAuthToken() : "";
|
|
5690
5769
|
return token ? { Authorization: `Bearer ${token}` } : {};
|
|
5691
5770
|
}, [context]);
|
|
5692
|
-
const reload =
|
|
5771
|
+
const reload = useCallback8(async () => {
|
|
5693
5772
|
if (!apiBase) {
|
|
5694
5773
|
setState(null);
|
|
5695
5774
|
setLoading(false);
|
|
@@ -5710,7 +5789,7 @@ function useBilling() {
|
|
|
5710
5789
|
useEffect11(() => {
|
|
5711
5790
|
void reload();
|
|
5712
5791
|
}, [reload]);
|
|
5713
|
-
const redirectVia =
|
|
5792
|
+
const redirectVia = useCallback8(
|
|
5714
5793
|
async (path, body) => {
|
|
5715
5794
|
if (!apiBase) throw new Error("Hub URL not configured");
|
|
5716
5795
|
const res = await fetch(`${apiBase}${path}`, {
|
|
@@ -5724,11 +5803,11 @@ function useBilling() {
|
|
|
5724
5803
|
},
|
|
5725
5804
|
[apiBase, authHeaders]
|
|
5726
5805
|
);
|
|
5727
|
-
const openCheckout =
|
|
5806
|
+
const openCheckout = useCallback8(
|
|
5728
5807
|
(priceRef, options = {}) => redirectVia("/billing/checkout", buildCheckoutBody(priceRef, options)),
|
|
5729
5808
|
[redirectVia]
|
|
5730
5809
|
);
|
|
5731
|
-
const openPortal =
|
|
5810
|
+
const openPortal = useCallback8(
|
|
5732
5811
|
(returnUrl) => redirectVia("/billing/portal", returnUrl ? { returnUrl } : {}),
|
|
5733
5812
|
[redirectVia]
|
|
5734
5813
|
);
|
|
@@ -5753,6 +5832,8 @@ export {
|
|
|
5753
5832
|
DemoBanner,
|
|
5754
5833
|
DemoDataExpiredScreen,
|
|
5755
5834
|
DemoQuotaIndicator,
|
|
5835
|
+
EntangleBus,
|
|
5836
|
+
EntangleProvider,
|
|
5756
5837
|
ErrorBoundary,
|
|
5757
5838
|
HubConnectScreen,
|
|
5758
5839
|
HubStatusIndicator,
|
|
@@ -5874,6 +5955,9 @@ export {
|
|
|
5874
5955
|
useEditorExtensions,
|
|
5875
5956
|
useEditorExtensionsSafe,
|
|
5876
5957
|
useEffectiveSchema,
|
|
5958
|
+
useEntangleBind,
|
|
5959
|
+
useEntangleBus,
|
|
5960
|
+
useEntangledHighlight,
|
|
5877
5961
|
useFileUpload,
|
|
5878
5962
|
useFind,
|
|
5879
5963
|
useGlobalUndo,
|
|
@@ -5901,6 +5985,7 @@ export {
|
|
|
5901
5985
|
usePlugins,
|
|
5902
5986
|
usePolicyFilteredReactionCounters,
|
|
5903
5987
|
usePresence,
|
|
5988
|
+
usePublishEntangleHover,
|
|
5904
5989
|
useQuery,
|
|
5905
5990
|
useRelatedRows,
|
|
5906
5991
|
useRemoteSchema,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xnetjs/react",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.5.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -46,15 +46,15 @@
|
|
|
46
46
|
"y-protocols": "^1.0.6",
|
|
47
47
|
"yjs": "^13.6.24",
|
|
48
48
|
"@xnetjs/billing": "0.0.2",
|
|
49
|
-
"@xnetjs/core": "2.
|
|
50
|
-
"@xnetjs/crypto": "2.
|
|
51
|
-
"@xnetjs/data": "2.
|
|
52
|
-
"@xnetjs/data-bridge": "2.
|
|
53
|
-
"@xnetjs/history": "2.
|
|
54
|
-
"@xnetjs/identity": "2.
|
|
55
|
-
"@xnetjs/plugins": "2.
|
|
56
|
-
"@xnetjs/runtime": "0.5.
|
|
57
|
-
"@xnetjs/sync": "2.
|
|
49
|
+
"@xnetjs/core": "2.5.0",
|
|
50
|
+
"@xnetjs/crypto": "2.5.0",
|
|
51
|
+
"@xnetjs/data": "2.5.0",
|
|
52
|
+
"@xnetjs/data-bridge": "2.5.0",
|
|
53
|
+
"@xnetjs/history": "2.5.0",
|
|
54
|
+
"@xnetjs/identity": "2.5.0",
|
|
55
|
+
"@xnetjs/plugins": "2.5.0",
|
|
56
|
+
"@xnetjs/runtime": "0.5.5",
|
|
57
|
+
"@xnetjs/sync": "2.5.0"
|
|
58
58
|
},
|
|
59
59
|
"peerDependencies": {
|
|
60
60
|
"react": "^18.0.0 || ^19.0.0"
|