@spoosh/react 0.11.0 → 0.13.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/README.md +143 -41
- package/dist/index.d.mts +306 -109
- package/dist/index.d.ts +306 -109
- package/dist/index.js +379 -56
- package/dist/index.mjs +390 -57
- package/package.json +11 -4
package/dist/index.js
CHANGED
|
@@ -404,12 +404,12 @@ function createUseWrite(options) {
|
|
|
404
404
|
return useWrite;
|
|
405
405
|
}
|
|
406
406
|
|
|
407
|
-
// src/
|
|
407
|
+
// src/usePages/index.ts
|
|
408
408
|
var import_react3 = require("react");
|
|
409
409
|
var import_core3 = require("@spoosh/core");
|
|
410
|
-
function
|
|
410
|
+
function createUsePages(options) {
|
|
411
411
|
const { api, stateManager, eventEmitter, pluginExecutor } = options;
|
|
412
|
-
return function
|
|
412
|
+
return function usePages(readFn, readOptions) {
|
|
413
413
|
const {
|
|
414
414
|
enabled = true,
|
|
415
415
|
tags,
|
|
@@ -432,7 +432,7 @@ function createUseInfiniteRead(options) {
|
|
|
432
432
|
const capturedCall = selectorResultRef.current.call;
|
|
433
433
|
if (!capturedCall) {
|
|
434
434
|
throw new Error(
|
|
435
|
-
'
|
|
435
|
+
'usePages requires calling an HTTP method (GET). Example: usePages((api) => api("posts").GET())'
|
|
436
436
|
);
|
|
437
437
|
}
|
|
438
438
|
const requestOptions = capturedCall.options;
|
|
@@ -442,12 +442,6 @@ function createUseInfiniteRead(options) {
|
|
|
442
442
|
params: requestOptions?.params,
|
|
443
443
|
body: requestOptions?.body
|
|
444
444
|
};
|
|
445
|
-
const baseOptionsForKey = {
|
|
446
|
-
...capturedCall.options,
|
|
447
|
-
query: void 0,
|
|
448
|
-
params: void 0,
|
|
449
|
-
body: void 0
|
|
450
|
-
};
|
|
451
445
|
const resolvedPath = (0, import_core3.resolvePath)(pathSegments, requestOptions?.params);
|
|
452
446
|
const resolvedTags = (0, import_core3.resolveTags)({ tags }, resolvedPath);
|
|
453
447
|
const canFetchNextRef = (0, import_react3.useRef)(canFetchNext);
|
|
@@ -463,22 +457,31 @@ function createUseInfiniteRead(options) {
|
|
|
463
457
|
const queryKey = stateManager.createQueryKey({
|
|
464
458
|
path: capturedCall.path,
|
|
465
459
|
method: capturedCall.method,
|
|
466
|
-
options:
|
|
460
|
+
options: capturedCall.options
|
|
461
|
+
});
|
|
462
|
+
const lifecycleRef = (0, import_react3.useRef)({
|
|
463
|
+
initialized: false,
|
|
464
|
+
prevContext: null,
|
|
465
|
+
lastQueryKey: null
|
|
467
466
|
});
|
|
468
467
|
const controllerRef = (0, import_react3.useRef)(null);
|
|
469
|
-
|
|
468
|
+
const queryKeyChanged = controllerRef.current !== null && controllerRef.current.queryKey !== queryKey;
|
|
469
|
+
if (queryKeyChanged) {
|
|
470
|
+
lifecycleRef.current.prevContext = controllerRef.current.controller.getContext();
|
|
471
|
+
lifecycleRef.current.initialized = false;
|
|
472
|
+
}
|
|
473
|
+
if (!controllerRef.current || queryKeyChanged) {
|
|
470
474
|
controllerRef.current = {
|
|
471
475
|
controller: (0, import_core3.createInfiniteReadController)({
|
|
472
476
|
path: capturedCall.path,
|
|
473
477
|
method: capturedCall.method,
|
|
474
478
|
tags: resolvedTags,
|
|
475
479
|
initialRequest,
|
|
476
|
-
|
|
477
|
-
canFetchNext: (ctx) => canFetchNextRef.current(ctx),
|
|
480
|
+
canFetchNext: canFetchNext ? (ctx) => canFetchNextRef.current?.(ctx) ?? false : void 0,
|
|
478
481
|
canFetchPrev: canFetchPrev ? (ctx) => canFetchPrevRef.current?.(ctx) ?? false : void 0,
|
|
479
|
-
nextPageRequest: (ctx) => nextPageRequestRef.current(ctx),
|
|
482
|
+
nextPageRequest: nextPageRequest ? (ctx) => nextPageRequestRef.current?.(ctx) ?? {} : void 0,
|
|
480
483
|
prevPageRequest: prevPageRequest ? (ctx) => prevPageRequestRef.current?.(ctx) ?? {} : void 0,
|
|
481
|
-
merger: (
|
|
484
|
+
merger: (pages) => mergerRef.current(pages),
|
|
482
485
|
stateManager,
|
|
483
486
|
eventEmitter,
|
|
484
487
|
pluginExecutor,
|
|
@@ -488,9 +491,7 @@ function createUseInfiniteRead(options) {
|
|
|
488
491
|
const method = pathMethods[capturedCall.method];
|
|
489
492
|
const fetchOptions = {
|
|
490
493
|
...capturedCall.options,
|
|
491
|
-
|
|
492
|
-
params: opts.params,
|
|
493
|
-
body: opts.body,
|
|
494
|
+
...opts,
|
|
494
495
|
signal
|
|
495
496
|
};
|
|
496
497
|
return method(fetchOptions);
|
|
@@ -501,11 +502,12 @@ function createUseInfiniteRead(options) {
|
|
|
501
502
|
}
|
|
502
503
|
const controller = controllerRef.current.controller;
|
|
503
504
|
controller.setPluginOptions(pluginOpts);
|
|
504
|
-
const
|
|
505
|
-
controller.subscribe,
|
|
506
|
-
controller
|
|
507
|
-
controller.getState
|
|
505
|
+
const subscribe = (0, import_react3.useCallback)(
|
|
506
|
+
(callback) => controller.subscribe(callback),
|
|
507
|
+
[controller]
|
|
508
508
|
);
|
|
509
|
+
const getSnapshot = (0, import_react3.useCallback)(() => controller.getState(), [controller]);
|
|
510
|
+
const state = (0, import_react3.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
|
|
509
511
|
const [isPending, setIsPending] = (0, import_react3.useState)(() => {
|
|
510
512
|
return enabled && state.data === void 0;
|
|
511
513
|
});
|
|
@@ -515,10 +517,6 @@ function createUseInfiniteRead(options) {
|
|
|
515
517
|
const fetchingPrev = fetchingDirection === "prev";
|
|
516
518
|
const hasData = state.data !== void 0;
|
|
517
519
|
const loading = (isPending || fetching) && !hasData;
|
|
518
|
-
const lifecycleRef = (0, import_react3.useRef)({
|
|
519
|
-
initialized: false,
|
|
520
|
-
prevContext: null
|
|
521
|
-
});
|
|
522
520
|
const tagsKey = JSON.stringify(tags);
|
|
523
521
|
(0, import_react3.useEffect)(() => {
|
|
524
522
|
return () => {
|
|
@@ -527,8 +525,27 @@ function createUseInfiniteRead(options) {
|
|
|
527
525
|
};
|
|
528
526
|
}, []);
|
|
529
527
|
(0, import_react3.useEffect)(() => {
|
|
530
|
-
|
|
531
|
-
|
|
528
|
+
if (!enabled) return;
|
|
529
|
+
const { initialized, prevContext, lastQueryKey } = lifecycleRef.current;
|
|
530
|
+
const isQueryKeyChange = lastQueryKey !== null && lastQueryKey !== queryKey;
|
|
531
|
+
if (!initialized) {
|
|
532
|
+
controller.mount();
|
|
533
|
+
lifecycleRef.current.initialized = true;
|
|
534
|
+
if (prevContext) {
|
|
535
|
+
controller.update(prevContext);
|
|
536
|
+
lifecycleRef.current.prevContext = null;
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
lifecycleRef.current.lastQueryKey = queryKey;
|
|
540
|
+
const currentState = controller.getState();
|
|
541
|
+
const isFetching = controller.getFetchingDirection() !== null;
|
|
542
|
+
if (isQueryKeyChange) {
|
|
543
|
+
setIsPending(true);
|
|
544
|
+
controller.trigger({ force: false }).finally(() => setIsPending(false));
|
|
545
|
+
} else if (currentState.data === void 0 && !isFetching) {
|
|
546
|
+
setIsPending(true);
|
|
547
|
+
controller.fetchNext().finally(() => setIsPending(false));
|
|
548
|
+
}
|
|
532
549
|
const unsubInvalidate = eventEmitter.on(
|
|
533
550
|
"invalidate",
|
|
534
551
|
(invalidatedTags) => {
|
|
@@ -537,41 +554,32 @@ function createUseInfiniteRead(options) {
|
|
|
537
554
|
);
|
|
538
555
|
if (hasMatch) {
|
|
539
556
|
setIsPending(true);
|
|
540
|
-
controller.
|
|
557
|
+
controller.trigger().finally(() => setIsPending(false));
|
|
541
558
|
}
|
|
542
559
|
}
|
|
543
560
|
);
|
|
544
561
|
const unsubRefetchAll = eventEmitter.on("refetchAll", () => {
|
|
545
562
|
setIsPending(true);
|
|
546
|
-
controller.
|
|
563
|
+
controller.trigger().finally(() => setIsPending(false));
|
|
547
564
|
});
|
|
548
565
|
return () => {
|
|
566
|
+
controller.unmount();
|
|
549
567
|
unsubInvalidate();
|
|
550
568
|
unsubRefetchAll();
|
|
551
569
|
};
|
|
552
|
-
}, [tagsKey]);
|
|
553
|
-
|
|
554
|
-
if (!lifecycleRef.current.initialized) return;
|
|
555
|
-
if (enabled) {
|
|
556
|
-
const currentState = controller.getState();
|
|
557
|
-
const isFetching = controller.getFetchingDirection() !== null;
|
|
558
|
-
if (currentState.data === void 0 && !isFetching) {
|
|
559
|
-
setIsPending(true);
|
|
560
|
-
controller.fetchNext().finally(() => setIsPending(false));
|
|
561
|
-
}
|
|
562
|
-
}
|
|
563
|
-
}, [enabled]);
|
|
570
|
+
}, [queryKey, enabled, tagsKey]);
|
|
571
|
+
const pluginOptsKey = JSON.stringify(pluginOpts);
|
|
564
572
|
(0, import_react3.useEffect)(() => {
|
|
565
573
|
if (!enabled || !lifecycleRef.current.initialized) return;
|
|
566
574
|
const prevContext = controller.getContext();
|
|
567
575
|
controller.update(prevContext);
|
|
568
|
-
}, [
|
|
569
|
-
const
|
|
570
|
-
|
|
576
|
+
}, [pluginOptsKey]);
|
|
577
|
+
const trigger = async (options2) => {
|
|
578
|
+
await controller.trigger(options2);
|
|
579
|
+
};
|
|
571
580
|
const result = {
|
|
572
|
-
meta: pluginResultData,
|
|
573
581
|
data: state.data,
|
|
574
|
-
|
|
582
|
+
pages: state.pages,
|
|
575
583
|
loading,
|
|
576
584
|
fetching,
|
|
577
585
|
fetchingNext,
|
|
@@ -580,7 +588,7 @@ function createUseInfiniteRead(options) {
|
|
|
580
588
|
canFetchPrev: state.canFetchPrev,
|
|
581
589
|
fetchNext: controller.fetchNext,
|
|
582
590
|
fetchPrev: controller.fetchPrev,
|
|
583
|
-
trigger
|
|
591
|
+
trigger,
|
|
584
592
|
abort: controller.abort,
|
|
585
593
|
error: state.error
|
|
586
594
|
};
|
|
@@ -654,32 +662,345 @@ function createUseQueue(options) {
|
|
|
654
662
|
return useQueue;
|
|
655
663
|
}
|
|
656
664
|
|
|
665
|
+
// src/useSubscription/index.ts
|
|
666
|
+
var import_react5 = require("react");
|
|
667
|
+
var import_core5 = require("@spoosh/core");
|
|
668
|
+
function createUseSubscription(options) {
|
|
669
|
+
const { stateManager, eventEmitter, pluginExecutor } = options;
|
|
670
|
+
function useSubscription(subFn, subOptions) {
|
|
671
|
+
const { enabled = true, adapter, operationType } = subOptions;
|
|
672
|
+
const selectorResultRef = (0, import_react5.useRef)({
|
|
673
|
+
call: null,
|
|
674
|
+
selector: null
|
|
675
|
+
});
|
|
676
|
+
const selectorProxy = (0, import_core5.createSelectorProxy)((result) => {
|
|
677
|
+
selectorResultRef.current = result;
|
|
678
|
+
});
|
|
679
|
+
subFn(selectorProxy);
|
|
680
|
+
const capturedCall = selectorResultRef.current.call;
|
|
681
|
+
if (!capturedCall) {
|
|
682
|
+
throw new Error("useSubscription requires calling a method");
|
|
683
|
+
}
|
|
684
|
+
const queryKey = stateManager.createQueryKey({
|
|
685
|
+
path: capturedCall.path,
|
|
686
|
+
method: capturedCall.method,
|
|
687
|
+
options: capturedCall.options
|
|
688
|
+
});
|
|
689
|
+
const controllerRef = (0, import_react5.useRef)(null);
|
|
690
|
+
const subscriptionVersionRef = (0, import_react5.useRef)(0);
|
|
691
|
+
const getOrCreateController = (0, import_react5.useCallback)(() => {
|
|
692
|
+
if (controllerRef.current) {
|
|
693
|
+
return controllerRef.current;
|
|
694
|
+
}
|
|
695
|
+
const controller = (0, import_core5.createSubscriptionController)({
|
|
696
|
+
channel: capturedCall.path,
|
|
697
|
+
baseAdapter: adapter,
|
|
698
|
+
stateManager,
|
|
699
|
+
eventEmitter,
|
|
700
|
+
pluginExecutor,
|
|
701
|
+
queryKey,
|
|
702
|
+
operationType,
|
|
703
|
+
path: capturedCall.path,
|
|
704
|
+
method: capturedCall.method
|
|
705
|
+
});
|
|
706
|
+
controllerRef.current = controller;
|
|
707
|
+
return controller;
|
|
708
|
+
}, [
|
|
709
|
+
queryKey,
|
|
710
|
+
adapter,
|
|
711
|
+
operationType,
|
|
712
|
+
capturedCall.path,
|
|
713
|
+
capturedCall.method
|
|
714
|
+
]);
|
|
715
|
+
const subscribe = (0, import_react5.useCallback)(
|
|
716
|
+
(callback) => {
|
|
717
|
+
const controller = getOrCreateController();
|
|
718
|
+
return controller.subscribe(callback);
|
|
719
|
+
},
|
|
720
|
+
[getOrCreateController]
|
|
721
|
+
);
|
|
722
|
+
const emptyStateRef = (0, import_react5.useRef)({
|
|
723
|
+
data: void 0,
|
|
724
|
+
error: void 0,
|
|
725
|
+
isConnected: false
|
|
726
|
+
});
|
|
727
|
+
const getSnapshot = (0, import_react5.useCallback)(() => {
|
|
728
|
+
if (!controllerRef.current) {
|
|
729
|
+
return emptyStateRef.current;
|
|
730
|
+
}
|
|
731
|
+
return controllerRef.current.getState();
|
|
732
|
+
}, []);
|
|
733
|
+
const state = (0, import_react5.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
|
|
734
|
+
const [isPending, setIsPending] = (0, import_react5.useState)(enabled);
|
|
735
|
+
(0, import_react5.useEffect)(() => {
|
|
736
|
+
if (!enabled) {
|
|
737
|
+
return;
|
|
738
|
+
}
|
|
739
|
+
setIsPending(true);
|
|
740
|
+
const controller = getOrCreateController();
|
|
741
|
+
controller.mount();
|
|
742
|
+
controller.subscribe();
|
|
743
|
+
return () => {
|
|
744
|
+
subscriptionVersionRef.current++;
|
|
745
|
+
controller.unsubscribe();
|
|
746
|
+
};
|
|
747
|
+
}, [queryKey, enabled, getOrCreateController]);
|
|
748
|
+
(0, import_react5.useEffect)(() => {
|
|
749
|
+
if (state.isConnected || state.data !== void 0 || state.error !== void 0) {
|
|
750
|
+
setIsPending(false);
|
|
751
|
+
}
|
|
752
|
+
}, [state.isConnected, state.data, state.error]);
|
|
753
|
+
const disconnect = (0, import_react5.useCallback)(() => {
|
|
754
|
+
subscriptionVersionRef.current++;
|
|
755
|
+
if (controllerRef.current) {
|
|
756
|
+
controllerRef.current.unsubscribe();
|
|
757
|
+
}
|
|
758
|
+
}, []);
|
|
759
|
+
const trigger = (0, import_react5.useCallback)(async () => {
|
|
760
|
+
setIsPending(true);
|
|
761
|
+
subscriptionVersionRef.current++;
|
|
762
|
+
const controller = getOrCreateController();
|
|
763
|
+
controller.unsubscribe();
|
|
764
|
+
controller.mount();
|
|
765
|
+
await controller.subscribe();
|
|
766
|
+
}, [getOrCreateController]);
|
|
767
|
+
const loading = isPending;
|
|
768
|
+
return {
|
|
769
|
+
meta: {},
|
|
770
|
+
data: state.data,
|
|
771
|
+
error: state.error,
|
|
772
|
+
loading,
|
|
773
|
+
isConnected: state.isConnected,
|
|
774
|
+
_queryKey: queryKey,
|
|
775
|
+
_subscriptionVersion: subscriptionVersionRef.current,
|
|
776
|
+
trigger,
|
|
777
|
+
disconnect
|
|
778
|
+
};
|
|
779
|
+
}
|
|
780
|
+
return useSubscription;
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
// src/useSSE/index.ts
|
|
784
|
+
var import_react6 = require("react");
|
|
785
|
+
var import_core6 = require("@spoosh/core");
|
|
786
|
+
var import_transport_sse = require("@spoosh/transport-sse");
|
|
787
|
+
function isSSETransport(transport) {
|
|
788
|
+
return "createSubscriptionAdapter" in transport && typeof transport.createSubscriptionAdapter === "function";
|
|
789
|
+
}
|
|
790
|
+
function createUseSSE(options) {
|
|
791
|
+
const { eventEmitter, transports, config } = options;
|
|
792
|
+
const useSubscription = createUseSubscription(options);
|
|
793
|
+
function useSSE(subFn, sseOptions) {
|
|
794
|
+
const {
|
|
795
|
+
enabled = true,
|
|
796
|
+
events,
|
|
797
|
+
parse = "auto",
|
|
798
|
+
accumulate = "replace",
|
|
799
|
+
maxRetries,
|
|
800
|
+
retryDelay
|
|
801
|
+
} = sseOptions ?? {};
|
|
802
|
+
const transport = transports.get("sse");
|
|
803
|
+
if (!transport) {
|
|
804
|
+
throw new Error(
|
|
805
|
+
"SSE transport not registered. Make sure to register an SSE transport before using useSSE."
|
|
806
|
+
);
|
|
807
|
+
}
|
|
808
|
+
if (!isSSETransport(transport)) {
|
|
809
|
+
throw new Error(
|
|
810
|
+
"SSE transport does not implement createSubscriptionAdapter."
|
|
811
|
+
);
|
|
812
|
+
}
|
|
813
|
+
const selectorResultRef = (0, import_react6.useRef)({
|
|
814
|
+
call: null,
|
|
815
|
+
selector: null
|
|
816
|
+
});
|
|
817
|
+
const selectorProxy = (0, import_core6.createSelectorProxy)((result) => {
|
|
818
|
+
selectorResultRef.current = result;
|
|
819
|
+
});
|
|
820
|
+
subFn(selectorProxy);
|
|
821
|
+
const capturedCall = selectorResultRef.current.call;
|
|
822
|
+
if (!capturedCall) {
|
|
823
|
+
throw new Error("useSSE requires calling a method");
|
|
824
|
+
}
|
|
825
|
+
const currentOptionsRef = (0, import_react6.useRef)(
|
|
826
|
+
capturedCall.options
|
|
827
|
+
);
|
|
828
|
+
const adapter = (0, import_react6.useMemo)(
|
|
829
|
+
() => transport.createSubscriptionAdapter({
|
|
830
|
+
channel: capturedCall.path,
|
|
831
|
+
method: capturedCall.method,
|
|
832
|
+
baseUrl: config.baseUrl,
|
|
833
|
+
globalHeaders: config.defaultOptions.headers,
|
|
834
|
+
getRequestOptions: () => currentOptionsRef.current,
|
|
835
|
+
eventEmitter,
|
|
836
|
+
devtoolMeta: events ? { listenedEvents: events } : void 0
|
|
837
|
+
}),
|
|
838
|
+
[capturedCall.path, capturedCall.method]
|
|
839
|
+
);
|
|
840
|
+
const [accumulatedData, setAccumulatedData] = (0, import_react6.useState)({});
|
|
841
|
+
const eventSet = (0, import_react6.useMemo)(
|
|
842
|
+
() => events ? new Set(events) : null,
|
|
843
|
+
[events?.join(",")]
|
|
844
|
+
);
|
|
845
|
+
const parseRef = (0, import_react6.useRef)(parse);
|
|
846
|
+
const accumulateRef = (0, import_react6.useRef)(accumulate);
|
|
847
|
+
parseRef.current = parse;
|
|
848
|
+
accumulateRef.current = accumulate;
|
|
849
|
+
const optionsRef = (0, import_react6.useRef)({
|
|
850
|
+
maxRetries,
|
|
851
|
+
retryDelay
|
|
852
|
+
});
|
|
853
|
+
optionsRef.current = { maxRetries, retryDelay };
|
|
854
|
+
const subscription = useSubscription(subFn, {
|
|
855
|
+
enabled,
|
|
856
|
+
adapter,
|
|
857
|
+
operationType: transport.operationType
|
|
858
|
+
});
|
|
859
|
+
const prevVersionRef = (0, import_react6.useRef)(subscription._subscriptionVersion);
|
|
860
|
+
const lastMessageIndexRef = (0, import_react6.useRef)({});
|
|
861
|
+
(0, import_react6.useEffect)(() => {
|
|
862
|
+
if (subscription._subscriptionVersion !== prevVersionRef.current) {
|
|
863
|
+
setAccumulatedData({});
|
|
864
|
+
lastMessageIndexRef.current = {};
|
|
865
|
+
}
|
|
866
|
+
prevVersionRef.current = subscription._subscriptionVersion;
|
|
867
|
+
}, [subscription._subscriptionVersion]);
|
|
868
|
+
(0, import_react6.useEffect)(() => {
|
|
869
|
+
const data = subscription.data;
|
|
870
|
+
if (!data) {
|
|
871
|
+
return;
|
|
872
|
+
}
|
|
873
|
+
if (eventSet && !eventSet.has(data.event)) {
|
|
874
|
+
return;
|
|
875
|
+
}
|
|
876
|
+
const parser = (0, import_transport_sse.resolveParser)(parseRef.current, data.event);
|
|
877
|
+
let parsed;
|
|
878
|
+
try {
|
|
879
|
+
parsed = parser(data.data);
|
|
880
|
+
} catch {
|
|
881
|
+
parsed = data.data;
|
|
882
|
+
}
|
|
883
|
+
if (parsed === void 0) {
|
|
884
|
+
return;
|
|
885
|
+
}
|
|
886
|
+
const accumulator = (0, import_transport_sse.resolveAccumulator)(accumulateRef.current, data.event);
|
|
887
|
+
const parsedObj = parsed;
|
|
888
|
+
const messageIndex = typeof parsedObj?.index === "number" ? parsedObj.index : void 0;
|
|
889
|
+
if (messageIndex !== void 0) {
|
|
890
|
+
const lastIndex = lastMessageIndexRef.current[data.event];
|
|
891
|
+
if (lastIndex !== void 0 && messageIndex < lastIndex) {
|
|
892
|
+
setAccumulatedData({});
|
|
893
|
+
lastMessageIndexRef.current = {};
|
|
894
|
+
}
|
|
895
|
+
lastMessageIndexRef.current[data.event] = messageIndex;
|
|
896
|
+
}
|
|
897
|
+
setAccumulatedData((prev) => {
|
|
898
|
+
const previousEventData = prev[data.event];
|
|
899
|
+
let newEventData;
|
|
900
|
+
try {
|
|
901
|
+
newEventData = accumulator(previousEventData, parsed);
|
|
902
|
+
} catch {
|
|
903
|
+
newEventData = parsed;
|
|
904
|
+
}
|
|
905
|
+
const newAccumulated = {
|
|
906
|
+
...prev,
|
|
907
|
+
[data.event]: newEventData
|
|
908
|
+
};
|
|
909
|
+
eventEmitter?.emit(
|
|
910
|
+
"spoosh:subscription:accumulate",
|
|
911
|
+
{
|
|
912
|
+
queryKey: subscription._queryKey,
|
|
913
|
+
eventType: data.event,
|
|
914
|
+
accumulatedData: newAccumulated,
|
|
915
|
+
timestamp: Date.now()
|
|
916
|
+
}
|
|
917
|
+
);
|
|
918
|
+
return newAccumulated;
|
|
919
|
+
});
|
|
920
|
+
}, [subscription.data, subscription._queryKey, eventSet]);
|
|
921
|
+
const reset = (0, import_react6.useCallback)(() => {
|
|
922
|
+
setAccumulatedData({});
|
|
923
|
+
}, []);
|
|
924
|
+
const trigger = (0, import_react6.useCallback)(
|
|
925
|
+
async (opts) => {
|
|
926
|
+
reset();
|
|
927
|
+
const triggerOpts = {
|
|
928
|
+
...opts ?? {},
|
|
929
|
+
maxRetries: optionsRef.current.maxRetries,
|
|
930
|
+
retryDelay: optionsRef.current.retryDelay
|
|
931
|
+
};
|
|
932
|
+
currentOptionsRef.current = {
|
|
933
|
+
...currentOptionsRef.current,
|
|
934
|
+
...triggerOpts
|
|
935
|
+
};
|
|
936
|
+
await subscription.trigger(triggerOpts);
|
|
937
|
+
},
|
|
938
|
+
[subscription.trigger, reset]
|
|
939
|
+
);
|
|
940
|
+
return {
|
|
941
|
+
data: Object.keys(accumulatedData).length ? accumulatedData : void 0,
|
|
942
|
+
error: subscription.error,
|
|
943
|
+
isConnected: subscription.isConnected,
|
|
944
|
+
loading: subscription.loading,
|
|
945
|
+
meta: {},
|
|
946
|
+
trigger,
|
|
947
|
+
disconnect: subscription.disconnect,
|
|
948
|
+
reset
|
|
949
|
+
};
|
|
950
|
+
}
|
|
951
|
+
return useSSE;
|
|
952
|
+
}
|
|
953
|
+
|
|
657
954
|
// src/create/index.ts
|
|
658
955
|
function create(instance) {
|
|
659
|
-
const { api, stateManager, eventEmitter, pluginExecutor } = instance;
|
|
956
|
+
const { api, stateManager, eventEmitter, pluginExecutor, transports } = instance;
|
|
660
957
|
const useRead = createUseRead({
|
|
661
958
|
api,
|
|
662
959
|
stateManager,
|
|
663
960
|
eventEmitter,
|
|
664
|
-
pluginExecutor
|
|
961
|
+
pluginExecutor,
|
|
962
|
+
transports,
|
|
963
|
+
config: instance.config
|
|
665
964
|
});
|
|
666
965
|
const useWrite = createUseWrite({
|
|
667
966
|
api,
|
|
668
967
|
stateManager,
|
|
669
968
|
eventEmitter,
|
|
670
|
-
pluginExecutor
|
|
969
|
+
pluginExecutor,
|
|
970
|
+
transports,
|
|
971
|
+
config: instance.config
|
|
671
972
|
});
|
|
672
|
-
const
|
|
973
|
+
const usePages = createUsePages({
|
|
673
974
|
api,
|
|
674
975
|
stateManager,
|
|
675
976
|
eventEmitter,
|
|
676
|
-
pluginExecutor
|
|
977
|
+
pluginExecutor,
|
|
978
|
+
transports,
|
|
979
|
+
config: instance.config
|
|
677
980
|
});
|
|
678
981
|
const useQueue = createUseQueue({
|
|
679
982
|
api,
|
|
680
983
|
stateManager,
|
|
681
984
|
eventEmitter,
|
|
682
|
-
pluginExecutor
|
|
985
|
+
pluginExecutor,
|
|
986
|
+
transports,
|
|
987
|
+
config: instance.config
|
|
988
|
+
});
|
|
989
|
+
const useSubscription = createUseSubscription({
|
|
990
|
+
api,
|
|
991
|
+
stateManager,
|
|
992
|
+
eventEmitter,
|
|
993
|
+
pluginExecutor,
|
|
994
|
+
transports,
|
|
995
|
+
config: instance.config
|
|
996
|
+
});
|
|
997
|
+
const useSSE = createUseSSE({
|
|
998
|
+
api,
|
|
999
|
+
stateManager,
|
|
1000
|
+
eventEmitter,
|
|
1001
|
+
pluginExecutor,
|
|
1002
|
+
transports,
|
|
1003
|
+
config: instance.config
|
|
683
1004
|
});
|
|
684
1005
|
const plugins = pluginExecutor.getPlugins();
|
|
685
1006
|
const setupContext = {
|
|
@@ -708,8 +1029,10 @@ function create(instance) {
|
|
|
708
1029
|
return {
|
|
709
1030
|
useRead,
|
|
710
1031
|
useWrite,
|
|
711
|
-
|
|
1032
|
+
usePages,
|
|
712
1033
|
useQueue,
|
|
1034
|
+
useSubscription,
|
|
1035
|
+
useSSE,
|
|
713
1036
|
...instanceApis
|
|
714
1037
|
};
|
|
715
1038
|
}
|