react-sync-ui 0.0.1
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/LICENSE +21 -0
- package/README.md +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.js +8 -0
- package/dist/react-sync-ui.cjs.development.js +128 -0
- package/dist/react-sync-ui.cjs.development.js.map +1 -0
- package/dist/react-sync-ui.cjs.production.min.js +2 -0
- package/dist/react-sync-ui.cjs.production.min.js.map +1 -0
- package/dist/react-sync-ui.esm.js +119 -0
- package/dist/react-sync-ui.esm.js.map +1 -0
- package/dist/syncUI.d.ts +19 -0
- package/package.json +54 -0
- package/src/index.ts +3 -0
- package/src/syncUI.tsx +133 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2021 Jakub Švehla
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# React sync ui
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
export declare const syncUIFactory: () => {
|
|
3
|
+
makeSyncUI: <ArgData, ResolveValue = void>(SyncUserComp: import("react").FC<{
|
|
4
|
+
data: ArgData;
|
|
5
|
+
resolve: (value: ResolveValue) => void;
|
|
6
|
+
reject: (reason?: any) => void;
|
|
7
|
+
}>) => (input: ArgData) => Promise<ResolveValue>;
|
|
8
|
+
RegisterSyncUI: () => JSX.Element;
|
|
9
|
+
};
|
|
10
|
+
export declare const makeSyncUI: <ArgData, ResolveValue = void>(SyncUserComp: import("react").FC<{
|
|
11
|
+
data: ArgData;
|
|
12
|
+
resolve: (value: ResolveValue) => void;
|
|
13
|
+
reject: (reason?: any) => void;
|
|
14
|
+
}>) => (input: ArgData) => Promise<ResolveValue>, RegisterSyncUI: () => JSX.Element;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
|
|
6
|
+
|
|
7
|
+
var React = require('react');
|
|
8
|
+
var React__default = _interopDefault(React);
|
|
9
|
+
|
|
10
|
+
var useComponentDidMount = function useComponentDidMount(fn) {
|
|
11
|
+
React.useEffect(fn, []);
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
var getSingletonCompCheck = function getSingletonCompCheck(errorMsg) {
|
|
15
|
+
var globalMountCounter = 0;
|
|
16
|
+
return function () {
|
|
17
|
+
useComponentDidMount(function () {
|
|
18
|
+
if (globalMountCounter > 0) throw new Error(errorMsg);
|
|
19
|
+
globalMountCounter++;
|
|
20
|
+
});
|
|
21
|
+
return React__default.createElement(React__default.Fragment, null);
|
|
22
|
+
};
|
|
23
|
+
}; // TODO: add docs + add tests
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
var useAsyncQueue = function useAsyncQueue() {
|
|
27
|
+
var _asyncQueue$, _asyncQueue$2;
|
|
28
|
+
|
|
29
|
+
var _useState = React.useState([]),
|
|
30
|
+
asyncQueue = _useState[0],
|
|
31
|
+
setAsyncQueue = _useState[1];
|
|
32
|
+
|
|
33
|
+
var registerToQueue = React.useCallback(function (type, data) {
|
|
34
|
+
return new Promise(function (resolve, reject) {
|
|
35
|
+
return setAsyncQueue(function (p) {
|
|
36
|
+
return [].concat(p, [{
|
|
37
|
+
type: type,
|
|
38
|
+
data: data,
|
|
39
|
+
resolve: resolve,
|
|
40
|
+
reject: reject
|
|
41
|
+
}]);
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
}, []);
|
|
45
|
+
var resolveHeadItem = React.useCallback(function (value) {
|
|
46
|
+
setAsyncQueue(function (queue) {
|
|
47
|
+
var first = queue[0],
|
|
48
|
+
rest = queue.slice(1);
|
|
49
|
+
first == null ? void 0 : first.resolve(value);
|
|
50
|
+
return rest;
|
|
51
|
+
});
|
|
52
|
+
}, []);
|
|
53
|
+
var rejectHeadItem = React.useCallback(function (reason) {
|
|
54
|
+
setAsyncQueue(function (queue) {
|
|
55
|
+
var first = queue[0],
|
|
56
|
+
rest = queue.slice(1);
|
|
57
|
+
first == null ? void 0 : first.reject(reason);
|
|
58
|
+
return rest;
|
|
59
|
+
});
|
|
60
|
+
}, []);
|
|
61
|
+
return {
|
|
62
|
+
head: asyncQueue[0] ? {
|
|
63
|
+
data: (_asyncQueue$ = asyncQueue[0]) == null ? void 0 : _asyncQueue$.data,
|
|
64
|
+
type: (_asyncQueue$2 = asyncQueue[0]) == null ? void 0 : _asyncQueue$2.type,
|
|
65
|
+
resolve: resolveHeadItem,
|
|
66
|
+
reject: rejectHeadItem
|
|
67
|
+
} : undefined,
|
|
68
|
+
registerToQueue: registerToQueue
|
|
69
|
+
};
|
|
70
|
+
};
|
|
71
|
+
var syncUIFactory = function syncUIFactory() {
|
|
72
|
+
var mutSyncUIComponentsRenderQueue = [];
|
|
73
|
+
var ThrowIfMoreInstances = getSingletonCompCheck("You have to init <RegisterSyncUI /> just one time");
|
|
74
|
+
return {
|
|
75
|
+
makeSyncUI: function makeSyncUI(SyncUserComp) {
|
|
76
|
+
var _ref, _SyncUserComp$display;
|
|
77
|
+
|
|
78
|
+
var _debugName = (_ref = (_SyncUserComp$display = SyncUserComp.displayName) != null ? _SyncUserComp$display : SyncUserComp.name) != null ? _ref : "uniqSymbolMessageType";
|
|
79
|
+
|
|
80
|
+
var syncUIComponentType = Symbol(_debugName); // object with the registerToQueue key has to be there to change returned mutable reference object while the function is already called
|
|
81
|
+
|
|
82
|
+
var singletonSyncUIRef = {
|
|
83
|
+
registerToQueue: undefined
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
var SyncUISingletonComp = function SyncUISingletonComp(props) {
|
|
87
|
+
useComponentDidMount(function () {
|
|
88
|
+
singletonSyncUIRef.registerToQueue = props.registerToQueue;
|
|
89
|
+
return function () {
|
|
90
|
+
return singletonSyncUIRef.registerToQueue = undefined;
|
|
91
|
+
};
|
|
92
|
+
});
|
|
93
|
+
if (!props.head) return null;
|
|
94
|
+
if (props.head.type !== syncUIComponentType) return null;
|
|
95
|
+
return React__default.createElement(SyncUserComp, {
|
|
96
|
+
data: props.head.data,
|
|
97
|
+
resolve: props.head.resolve,
|
|
98
|
+
reject: props.head.reject
|
|
99
|
+
});
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
mutSyncUIComponentsRenderQueue.push(SyncUISingletonComp);
|
|
103
|
+
return function (input) {
|
|
104
|
+
if (!singletonSyncUIRef.registerToQueue) throw new Error("You have to initialize <RegisterSyncUI />");
|
|
105
|
+
return singletonSyncUIRef.registerToQueue(syncUIComponentType, input);
|
|
106
|
+
};
|
|
107
|
+
},
|
|
108
|
+
RegisterSyncUI: function RegisterSyncUI() {
|
|
109
|
+
var queue = useAsyncQueue();
|
|
110
|
+
return React__default.createElement(React__default.Fragment, null, React__default.createElement(ThrowIfMoreInstances, null), mutSyncUIComponentsRenderQueue.map(function (SyncComp, key) {
|
|
111
|
+
return React__default.createElement(React__default.Fragment, {
|
|
112
|
+
key: key
|
|
113
|
+
}, React__default.createElement(SyncComp, Object.assign({}, queue)));
|
|
114
|
+
}));
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
var syncUIFactory$1 = syncUIFactory;
|
|
120
|
+
|
|
121
|
+
var _syncUIFactory2 = /*#__PURE__*/syncUIFactory$1(),
|
|
122
|
+
makeSyncUI = _syncUIFactory2.makeSyncUI,
|
|
123
|
+
RegisterSyncUI = _syncUIFactory2.RegisterSyncUI;
|
|
124
|
+
|
|
125
|
+
exports.RegisterSyncUI = RegisterSyncUI;
|
|
126
|
+
exports.makeSyncUI = makeSyncUI;
|
|
127
|
+
exports.syncUIFactory = syncUIFactory$1;
|
|
128
|
+
//# sourceMappingURL=react-sync-ui.cjs.development.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"react-sync-ui.cjs.development.js","sources":["../src/syncUI.tsx","../src/index.ts"],"sourcesContent":["import React, { useCallback, useEffect, useState } from \"react\";\n\nexport const useComponentDidMount = (fn: Parameters<typeof useEffect>[0]) => {\n useEffect(fn, []);\n};\n\nconst getSingletonCompCheck = (errorMsg: string) => {\n let globalMountCounter = 0;\n\n return () => {\n useComponentDidMount(() => {\n if (globalMountCounter > 0) throw new Error(errorMsg);\n globalMountCounter++;\n });\n return <React.Fragment />;\n };\n};\n\n// TODO: add docs + add tests\nexport const useAsyncQueue = <Data, ResolveValue = void>() => {\n const [asyncQueue, setAsyncQueue] = useState(\n [] as {\n // TODO: rename type into typeId\n type: Symbol;\n data: Data;\n resolve: (arg: ResolveValue) => void;\n reject: (arg: any) => void;\n }[]\n );\n\n const registerToQueue = useCallback((type: Symbol, data: Data) => {\n return new Promise<ResolveValue>((resolve, reject) => setAsyncQueue(p => [...p, { type, data, resolve, reject }]));\n }, []);\n\n const resolveHeadItem = useCallback((value: ResolveValue) => {\n setAsyncQueue(queue => {\n const [first, ...rest] = queue;\n first?.resolve(value);\n return rest;\n });\n }, []);\n\n const rejectHeadItem = useCallback((reason?: any) => {\n setAsyncQueue(queue => {\n const [first, ...rest] = queue;\n first?.reject(reason);\n return rest;\n });\n }, []);\n\n return {\n head: asyncQueue[0]\n ? {\n data: asyncQueue[0]?.data,\n type: asyncQueue[0]?.type,\n resolve: resolveHeadItem,\n reject: rejectHeadItem\n }\n : undefined,\n registerToQueue\n };\n};\n// https://github.com/jaredpalmer/tsdx/issues/200???\n// TODO: there is tsdx old typescript parser and new ts fancy syntax is not working...\n// type QueueItem<Data, ResolveValue> = ReturnType<typeof useAsyncQueue<any, any>>\ntype QueueItem<Data, ResolveValue> = {\n head:\n | {\n data: Data;\n type: Symbol;\n resolve: (value: ResolveValue) => void;\n reject: (reason?: any) => void;\n }\n | undefined;\n registerToQueue: (type: Symbol, data: Data) => Promise<ResolveValue>;\n};\n\nexport const syncUIFactory = () => {\n const mutSyncUIComponentsRenderQueue = [] as React.FC<QueueItem<any, any>>[];\n\n const ThrowIfMoreInstances = getSingletonCompCheck(\"You have to init <RegisterSyncUI /> just one time\");\n\n return {\n makeSyncUI: <ArgData, ResolveValue = void>(\n SyncUserComp: React.FC<{\n data: ArgData;\n resolve: (value: ResolveValue) => void;\n reject: (reason?: any) => void;\n }>\n ) => {\n const _debugName = SyncUserComp.displayName ?? SyncUserComp.name ?? \"uniqSymbolMessageType\";\n\n const syncUIComponentType = Symbol(_debugName);\n\n // object with the registerToQueue key has to be there to change returned mutable reference object while the function is already called\n const singletonSyncUIRef = {\n registerToQueue: undefined as undefined | QueueItem<ArgData, ResolveValue>[\"registerToQueue\"]\n };\n\n const SyncUISingletonComp = (props: QueueItem<ArgData, ResolveValue>) => {\n useComponentDidMount(() => {\n singletonSyncUIRef.registerToQueue = props.registerToQueue;\n return () => (singletonSyncUIRef.registerToQueue = undefined);\n });\n\n if (!props.head) return null;\n if (props.head.type !== syncUIComponentType) return null;\n\n return <SyncUserComp data={props.head.data} resolve={props.head.resolve} reject={props.head.reject} />;\n };\n\n mutSyncUIComponentsRenderQueue.push(SyncUISingletonComp);\n\n return (input: ArgData) => {\n if (!singletonSyncUIRef.registerToQueue) throw new Error(`You have to initialize <RegisterSyncUI />`);\n return singletonSyncUIRef.registerToQueue(syncUIComponentType, input);\n };\n },\n RegisterSyncUI: () => {\n const queue = useAsyncQueue();\n return (\n <>\n <ThrowIfMoreInstances />\n {mutSyncUIComponentsRenderQueue.map((SyncComp, key) => (\n <React.Fragment key={key}>\n <SyncComp {...queue} />\n </React.Fragment>\n ))}\n </>\n );\n }\n };\n};\n","import { syncUIFactory as _syncUIFactory } from \"./syncUI\";\nexport const syncUIFactory = _syncUIFactory;\nexport const { makeSyncUI, RegisterSyncUI } = syncUIFactory();\n"],"names":["useComponentDidMount","fn","useEffect","getSingletonCompCheck","errorMsg","globalMountCounter","Error","React","Fragment","useAsyncQueue","useState","asyncQueue","setAsyncQueue","registerToQueue","useCallback","type","data","Promise","resolve","reject","p","resolveHeadItem","value","queue","first","rest","rejectHeadItem","reason","head","undefined","syncUIFactory","mutSyncUIComponentsRenderQueue","ThrowIfMoreInstances","makeSyncUI","SyncUserComp","_debugName","displayName","name","syncUIComponentType","Symbol","singletonSyncUIRef","SyncUISingletonComp","props","push","input","RegisterSyncUI","map","SyncComp","key","_syncUIFactory"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e,t=require("react"),r=(e=t)&&"object"==typeof e&&"default"in e?e.default:e,n=function(e){t.useEffect(e,[])},u=function(){var e,u=[],o=(e=0,function(){return n((function(){if(e>0)throw new Error("You have to init <RegisterSyncUI /> just one time");e++})),r.createElement(r.Fragment,null)});return{makeSyncUI:function(e){var t,o,a=null!=(t=null!=(o=e.displayName)?o:e.name)?t:"uniqSymbolMessageType",i=Symbol(a),c={registerToQueue:void 0};return u.push((function(t){return n((function(){return c.registerToQueue=t.registerToQueue,function(){return c.registerToQueue=void 0}})),t.head?t.head.type!==i?null:r.createElement(e,{data:t.head.data,resolve:t.head.resolve,reject:t.head.reject}):null})),function(e){if(!c.registerToQueue)throw new Error("You have to initialize <RegisterSyncUI />");return c.registerToQueue(i,e)}},RegisterSyncUI:function(){var e,n,a,i,c,l,s,f,d=(i=(a=t.useState([]))[0],c=a[1],l=t.useCallback((function(e,t){return new Promise((function(r,n){return c((function(u){return[].concat(u,[{type:e,data:t,resolve:r,reject:n}])}))}))}),[]),s=t.useCallback((function(e){c((function(t){var r=t[0],n=t.slice(1);return null==r||r.resolve(e),n}))}),[]),f=t.useCallback((function(e){c((function(t){var r=t[0],n=t.slice(1);return null==r||r.reject(e),n}))}),[]),{head:i[0]?{data:null==(e=i[0])?void 0:e.data,type:null==(n=i[0])?void 0:n.type,resolve:s,reject:f}:void 0,registerToQueue:l});return r.createElement(r.Fragment,null,r.createElement(o,null),u.map((function(e,t){return r.createElement(r.Fragment,{key:t},r.createElement(e,Object.assign({},d)))})))}}},o=u(),a=o.makeSyncUI;exports.RegisterSyncUI=o.RegisterSyncUI,exports.makeSyncUI=a,exports.syncUIFactory=u;
|
|
2
|
+
//# sourceMappingURL=react-sync-ui.cjs.production.min.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"react-sync-ui.cjs.production.min.js","sources":["../src/syncUI.tsx","../src/index.ts"],"sourcesContent":["import React, { useCallback, useEffect, useState } from \"react\";\n\nexport const useComponentDidMount = (fn: Parameters<typeof useEffect>[0]) => {\n useEffect(fn, []);\n};\n\nconst getSingletonCompCheck = (errorMsg: string) => {\n let globalMountCounter = 0;\n\n return () => {\n useComponentDidMount(() => {\n if (globalMountCounter > 0) throw new Error(errorMsg);\n globalMountCounter++;\n });\n return <React.Fragment />;\n };\n};\n\n// TODO: add docs + add tests\nexport const useAsyncQueue = <Data, ResolveValue = void>() => {\n const [asyncQueue, setAsyncQueue] = useState(\n [] as {\n // TODO: rename type into typeId\n type: Symbol;\n data: Data;\n resolve: (arg: ResolveValue) => void;\n reject: (arg: any) => void;\n }[]\n );\n\n const registerToQueue = useCallback((type: Symbol, data: Data) => {\n return new Promise<ResolveValue>((resolve, reject) => setAsyncQueue(p => [...p, { type, data, resolve, reject }]));\n }, []);\n\n const resolveHeadItem = useCallback((value: ResolveValue) => {\n setAsyncQueue(queue => {\n const [first, ...rest] = queue;\n first?.resolve(value);\n return rest;\n });\n }, []);\n\n const rejectHeadItem = useCallback((reason?: any) => {\n setAsyncQueue(queue => {\n const [first, ...rest] = queue;\n first?.reject(reason);\n return rest;\n });\n }, []);\n\n return {\n head: asyncQueue[0]\n ? {\n data: asyncQueue[0]?.data,\n type: asyncQueue[0]?.type,\n resolve: resolveHeadItem,\n reject: rejectHeadItem\n }\n : undefined,\n registerToQueue\n };\n};\n// https://github.com/jaredpalmer/tsdx/issues/200???\n// TODO: there is tsdx old typescript parser and new ts fancy syntax is not working...\n// type QueueItem<Data, ResolveValue> = ReturnType<typeof useAsyncQueue<any, any>>\ntype QueueItem<Data, ResolveValue> = {\n head:\n | {\n data: Data;\n type: Symbol;\n resolve: (value: ResolveValue) => void;\n reject: (reason?: any) => void;\n }\n | undefined;\n registerToQueue: (type: Symbol, data: Data) => Promise<ResolveValue>;\n};\n\nexport const syncUIFactory = () => {\n const mutSyncUIComponentsRenderQueue = [] as React.FC<QueueItem<any, any>>[];\n\n const ThrowIfMoreInstances = getSingletonCompCheck(\"You have to init <RegisterSyncUI /> just one time\");\n\n return {\n makeSyncUI: <ArgData, ResolveValue = void>(\n SyncUserComp: React.FC<{\n data: ArgData;\n resolve: (value: ResolveValue) => void;\n reject: (reason?: any) => void;\n }>\n ) => {\n const _debugName = SyncUserComp.displayName ?? SyncUserComp.name ?? \"uniqSymbolMessageType\";\n\n const syncUIComponentType = Symbol(_debugName);\n\n // object with the registerToQueue key has to be there to change returned mutable reference object while the function is already called\n const singletonSyncUIRef = {\n registerToQueue: undefined as undefined | QueueItem<ArgData, ResolveValue>[\"registerToQueue\"]\n };\n\n const SyncUISingletonComp = (props: QueueItem<ArgData, ResolveValue>) => {\n useComponentDidMount(() => {\n singletonSyncUIRef.registerToQueue = props.registerToQueue;\n return () => (singletonSyncUIRef.registerToQueue = undefined);\n });\n\n if (!props.head) return null;\n if (props.head.type !== syncUIComponentType) return null;\n\n return <SyncUserComp data={props.head.data} resolve={props.head.resolve} reject={props.head.reject} />;\n };\n\n mutSyncUIComponentsRenderQueue.push(SyncUISingletonComp);\n\n return (input: ArgData) => {\n if (!singletonSyncUIRef.registerToQueue) throw new Error(`You have to initialize <RegisterSyncUI />`);\n return singletonSyncUIRef.registerToQueue(syncUIComponentType, input);\n };\n },\n RegisterSyncUI: () => {\n const queue = useAsyncQueue();\n return (\n <>\n <ThrowIfMoreInstances />\n {mutSyncUIComponentsRenderQueue.map((SyncComp, key) => (\n <React.Fragment key={key}>\n <SyncComp {...queue} />\n </React.Fragment>\n ))}\n </>\n );\n }\n };\n};\n","import { syncUIFactory as _syncUIFactory } from \"./syncUI\";\nexport const syncUIFactory = _syncUIFactory;\nexport const { makeSyncUI, RegisterSyncUI } = syncUIFactory();\n"],"names":["useComponentDidMount","fn","useEffect","syncUIFactory","globalMountCounter","mutSyncUIComponentsRenderQueue","ThrowIfMoreInstances","Error","React","Fragment","makeSyncUI","SyncUserComp","_debugName","displayName","name","syncUIComponentType","Symbol","singletonSyncUIRef","registerToQueue","undefined","push","props","head","type","data","resolve","reject","input","RegisterSyncUI","asyncQueue","setAsyncQueue","resolveHeadItem","rejectHeadItem","queue","useState","useCallback","Promise","p","value","first","rest","reason","_asyncQueue$","_asyncQueue$2","map","SyncComp","key"],"mappings":"oJAEaA,EAAuB,SAACC,GACnCC,YAAUD,EAAI,KCFHE,ED4EgB,eAtEvBC,EAuEEC,EAAiC,GAEjCC,GAzEFF,EAAqB,EAElB,kBACLJ,GAAqB,cACfI,EAAqB,EAAG,MAAM,IAAIG,MAqES,qDApE/CH,OAEKI,gBAACA,EAAMC,uBAoET,CACLC,WAAY,SACVC,WAMMC,oBAAaD,EAAaE,eAAeF,EAAaG,QAAQ,wBAE9DC,EAAsBC,OAAOJ,GAG7BK,EAAqB,CACzBC,qBAAiBC,UAenBd,EAA+Be,MAZH,SAACC,UAC3BrB,GAAqB,kBACnBiB,EAAmBC,gBAAkBG,EAAMH,gBACpC,kBAAOD,EAAmBC,qBAAkBC,MAGhDE,EAAMC,KACPD,EAAMC,KAAKC,OAASR,EAA4B,KAE7CP,gBAACG,GAAaa,KAAMH,EAAMC,KAAKE,KAAMC,QAASJ,EAAMC,KAAKG,QAASC,OAAQL,EAAMC,KAAKI,SAHpE,QAQnB,SAACC,OACDV,EAAmBC,gBAAiB,MAAM,IAAIX,0DAC5CU,EAAmBC,gBAAgBH,EAAqBY,KAGnEC,eAAgB,qBAlGXC,EAAYC,EAUbZ,EAIAa,EAQAC,EA6EIC,GAnGHJ,KAA6BK,WAClC,QADiBJ,OAUbZ,EAAkBiB,eAAY,SAACZ,EAAcC,UAC1C,IAAIY,SAAsB,SAACX,EAASC,UAAWI,GAAc,SAAAO,mBAASA,GAAG,CAAEd,KAAAA,EAAMC,KAAAA,EAAMC,QAAAA,EAASC,OAAAA,aACtG,IAEGK,EAAkBI,eAAY,SAACG,GACnCR,GAAc,SAAAG,OACLM,EAAkBN,KAARO,EAAQP,wBACzBM,GAAAA,EAAOd,QAAQa,GACRE,OAER,IAEGR,EAAiBG,eAAY,SAACM,GAClCX,GAAc,SAAAG,OACLM,EAAkBN,KAARO,EAAQP,wBACzBM,GAAAA,EAAOb,OAAOe,GACPD,OAER,IAEI,CACLlB,KAAMO,EAAW,GACb,CACEL,cAAMK,EAAW,WAAXa,EAAelB,KACrBD,cAAMM,EAAW,WAAXc,EAAepB,KACrBE,QAASM,EACTL,OAAQM,QAEVb,EACJD,gBAAAA,WA8DIV,gCACEA,gBAACF,QACAD,EAA+BuC,KAAI,SAACC,EAAUC,UAC7CtC,gBAACA,EAAMC,UAASqC,IAAKA,GACnBtC,gBAACqC,mBAAaZ,cC3HkB9B,IAA/BO,IAAAA,oCAAYkB"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import React, { useState, useCallback, useEffect } from 'react';
|
|
2
|
+
|
|
3
|
+
var useComponentDidMount = function useComponentDidMount(fn) {
|
|
4
|
+
useEffect(fn, []);
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
var getSingletonCompCheck = function getSingletonCompCheck(errorMsg) {
|
|
8
|
+
var globalMountCounter = 0;
|
|
9
|
+
return function () {
|
|
10
|
+
useComponentDidMount(function () {
|
|
11
|
+
if (globalMountCounter > 0) throw new Error(errorMsg);
|
|
12
|
+
globalMountCounter++;
|
|
13
|
+
});
|
|
14
|
+
return React.createElement(React.Fragment, null);
|
|
15
|
+
};
|
|
16
|
+
}; // TODO: add docs + add tests
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
var useAsyncQueue = function useAsyncQueue() {
|
|
20
|
+
var _asyncQueue$, _asyncQueue$2;
|
|
21
|
+
|
|
22
|
+
var _useState = useState([]),
|
|
23
|
+
asyncQueue = _useState[0],
|
|
24
|
+
setAsyncQueue = _useState[1];
|
|
25
|
+
|
|
26
|
+
var registerToQueue = useCallback(function (type, data) {
|
|
27
|
+
return new Promise(function (resolve, reject) {
|
|
28
|
+
return setAsyncQueue(function (p) {
|
|
29
|
+
return [].concat(p, [{
|
|
30
|
+
type: type,
|
|
31
|
+
data: data,
|
|
32
|
+
resolve: resolve,
|
|
33
|
+
reject: reject
|
|
34
|
+
}]);
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
}, []);
|
|
38
|
+
var resolveHeadItem = useCallback(function (value) {
|
|
39
|
+
setAsyncQueue(function (queue) {
|
|
40
|
+
var first = queue[0],
|
|
41
|
+
rest = queue.slice(1);
|
|
42
|
+
first == null ? void 0 : first.resolve(value);
|
|
43
|
+
return rest;
|
|
44
|
+
});
|
|
45
|
+
}, []);
|
|
46
|
+
var rejectHeadItem = useCallback(function (reason) {
|
|
47
|
+
setAsyncQueue(function (queue) {
|
|
48
|
+
var first = queue[0],
|
|
49
|
+
rest = queue.slice(1);
|
|
50
|
+
first == null ? void 0 : first.reject(reason);
|
|
51
|
+
return rest;
|
|
52
|
+
});
|
|
53
|
+
}, []);
|
|
54
|
+
return {
|
|
55
|
+
head: asyncQueue[0] ? {
|
|
56
|
+
data: (_asyncQueue$ = asyncQueue[0]) == null ? void 0 : _asyncQueue$.data,
|
|
57
|
+
type: (_asyncQueue$2 = asyncQueue[0]) == null ? void 0 : _asyncQueue$2.type,
|
|
58
|
+
resolve: resolveHeadItem,
|
|
59
|
+
reject: rejectHeadItem
|
|
60
|
+
} : undefined,
|
|
61
|
+
registerToQueue: registerToQueue
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
var syncUIFactory = function syncUIFactory() {
|
|
65
|
+
var mutSyncUIComponentsRenderQueue = [];
|
|
66
|
+
var ThrowIfMoreInstances = getSingletonCompCheck("You have to init <RegisterSyncUI /> just one time");
|
|
67
|
+
return {
|
|
68
|
+
makeSyncUI: function makeSyncUI(SyncUserComp) {
|
|
69
|
+
var _ref, _SyncUserComp$display;
|
|
70
|
+
|
|
71
|
+
var _debugName = (_ref = (_SyncUserComp$display = SyncUserComp.displayName) != null ? _SyncUserComp$display : SyncUserComp.name) != null ? _ref : "uniqSymbolMessageType";
|
|
72
|
+
|
|
73
|
+
var syncUIComponentType = Symbol(_debugName); // object with the registerToQueue key has to be there to change returned mutable reference object while the function is already called
|
|
74
|
+
|
|
75
|
+
var singletonSyncUIRef = {
|
|
76
|
+
registerToQueue: undefined
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
var SyncUISingletonComp = function SyncUISingletonComp(props) {
|
|
80
|
+
useComponentDidMount(function () {
|
|
81
|
+
singletonSyncUIRef.registerToQueue = props.registerToQueue;
|
|
82
|
+
return function () {
|
|
83
|
+
return singletonSyncUIRef.registerToQueue = undefined;
|
|
84
|
+
};
|
|
85
|
+
});
|
|
86
|
+
if (!props.head) return null;
|
|
87
|
+
if (props.head.type !== syncUIComponentType) return null;
|
|
88
|
+
return React.createElement(SyncUserComp, {
|
|
89
|
+
data: props.head.data,
|
|
90
|
+
resolve: props.head.resolve,
|
|
91
|
+
reject: props.head.reject
|
|
92
|
+
});
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
mutSyncUIComponentsRenderQueue.push(SyncUISingletonComp);
|
|
96
|
+
return function (input) {
|
|
97
|
+
if (!singletonSyncUIRef.registerToQueue) throw new Error("You have to initialize <RegisterSyncUI />");
|
|
98
|
+
return singletonSyncUIRef.registerToQueue(syncUIComponentType, input);
|
|
99
|
+
};
|
|
100
|
+
},
|
|
101
|
+
RegisterSyncUI: function RegisterSyncUI() {
|
|
102
|
+
var queue = useAsyncQueue();
|
|
103
|
+
return React.createElement(React.Fragment, null, React.createElement(ThrowIfMoreInstances, null), mutSyncUIComponentsRenderQueue.map(function (SyncComp, key) {
|
|
104
|
+
return React.createElement(React.Fragment, {
|
|
105
|
+
key: key
|
|
106
|
+
}, React.createElement(SyncComp, Object.assign({}, queue)));
|
|
107
|
+
}));
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
var syncUIFactory$1 = syncUIFactory;
|
|
113
|
+
|
|
114
|
+
var _syncUIFactory2 = /*#__PURE__*/syncUIFactory$1(),
|
|
115
|
+
makeSyncUI = _syncUIFactory2.makeSyncUI,
|
|
116
|
+
RegisterSyncUI = _syncUIFactory2.RegisterSyncUI;
|
|
117
|
+
|
|
118
|
+
export { RegisterSyncUI, makeSyncUI, syncUIFactory$1 as syncUIFactory };
|
|
119
|
+
//# sourceMappingURL=react-sync-ui.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"react-sync-ui.esm.js","sources":["../src/syncUI.tsx","../src/index.ts"],"sourcesContent":["import React, { useCallback, useEffect, useState } from \"react\";\n\nexport const useComponentDidMount = (fn: Parameters<typeof useEffect>[0]) => {\n useEffect(fn, []);\n};\n\nconst getSingletonCompCheck = (errorMsg: string) => {\n let globalMountCounter = 0;\n\n return () => {\n useComponentDidMount(() => {\n if (globalMountCounter > 0) throw new Error(errorMsg);\n globalMountCounter++;\n });\n return <React.Fragment />;\n };\n};\n\n// TODO: add docs + add tests\nexport const useAsyncQueue = <Data, ResolveValue = void>() => {\n const [asyncQueue, setAsyncQueue] = useState(\n [] as {\n // TODO: rename type into typeId\n type: Symbol;\n data: Data;\n resolve: (arg: ResolveValue) => void;\n reject: (arg: any) => void;\n }[]\n );\n\n const registerToQueue = useCallback((type: Symbol, data: Data) => {\n return new Promise<ResolveValue>((resolve, reject) => setAsyncQueue(p => [...p, { type, data, resolve, reject }]));\n }, []);\n\n const resolveHeadItem = useCallback((value: ResolveValue) => {\n setAsyncQueue(queue => {\n const [first, ...rest] = queue;\n first?.resolve(value);\n return rest;\n });\n }, []);\n\n const rejectHeadItem = useCallback((reason?: any) => {\n setAsyncQueue(queue => {\n const [first, ...rest] = queue;\n first?.reject(reason);\n return rest;\n });\n }, []);\n\n return {\n head: asyncQueue[0]\n ? {\n data: asyncQueue[0]?.data,\n type: asyncQueue[0]?.type,\n resolve: resolveHeadItem,\n reject: rejectHeadItem\n }\n : undefined,\n registerToQueue\n };\n};\n// https://github.com/jaredpalmer/tsdx/issues/200???\n// TODO: there is tsdx old typescript parser and new ts fancy syntax is not working...\n// type QueueItem<Data, ResolveValue> = ReturnType<typeof useAsyncQueue<any, any>>\ntype QueueItem<Data, ResolveValue> = {\n head:\n | {\n data: Data;\n type: Symbol;\n resolve: (value: ResolveValue) => void;\n reject: (reason?: any) => void;\n }\n | undefined;\n registerToQueue: (type: Symbol, data: Data) => Promise<ResolveValue>;\n};\n\nexport const syncUIFactory = () => {\n const mutSyncUIComponentsRenderQueue = [] as React.FC<QueueItem<any, any>>[];\n\n const ThrowIfMoreInstances = getSingletonCompCheck(\"You have to init <RegisterSyncUI /> just one time\");\n\n return {\n makeSyncUI: <ArgData, ResolveValue = void>(\n SyncUserComp: React.FC<{\n data: ArgData;\n resolve: (value: ResolveValue) => void;\n reject: (reason?: any) => void;\n }>\n ) => {\n const _debugName = SyncUserComp.displayName ?? SyncUserComp.name ?? \"uniqSymbolMessageType\";\n\n const syncUIComponentType = Symbol(_debugName);\n\n // object with the registerToQueue key has to be there to change returned mutable reference object while the function is already called\n const singletonSyncUIRef = {\n registerToQueue: undefined as undefined | QueueItem<ArgData, ResolveValue>[\"registerToQueue\"]\n };\n\n const SyncUISingletonComp = (props: QueueItem<ArgData, ResolveValue>) => {\n useComponentDidMount(() => {\n singletonSyncUIRef.registerToQueue = props.registerToQueue;\n return () => (singletonSyncUIRef.registerToQueue = undefined);\n });\n\n if (!props.head) return null;\n if (props.head.type !== syncUIComponentType) return null;\n\n return <SyncUserComp data={props.head.data} resolve={props.head.resolve} reject={props.head.reject} />;\n };\n\n mutSyncUIComponentsRenderQueue.push(SyncUISingletonComp);\n\n return (input: ArgData) => {\n if (!singletonSyncUIRef.registerToQueue) throw new Error(`You have to initialize <RegisterSyncUI />`);\n return singletonSyncUIRef.registerToQueue(syncUIComponentType, input);\n };\n },\n RegisterSyncUI: () => {\n const queue = useAsyncQueue();\n return (\n <>\n <ThrowIfMoreInstances />\n {mutSyncUIComponentsRenderQueue.map((SyncComp, key) => (\n <React.Fragment key={key}>\n <SyncComp {...queue} />\n </React.Fragment>\n ))}\n </>\n );\n }\n };\n};\n","import { syncUIFactory as _syncUIFactory } from \"./syncUI\";\nexport const syncUIFactory = _syncUIFactory;\nexport const { makeSyncUI, RegisterSyncUI } = syncUIFactory();\n"],"names":["useComponentDidMount","fn","useEffect","getSingletonCompCheck","errorMsg","globalMountCounter","Error","React","Fragment","useAsyncQueue","useState","asyncQueue","setAsyncQueue","registerToQueue","useCallback","type","data","Promise","resolve","reject","p","resolveHeadItem","value","queue","first","rest","rejectHeadItem","reason","head","undefined","syncUIFactory","mutSyncUIComponentsRenderQueue","ThrowIfMoreInstances","makeSyncUI","SyncUserComp","_debugName","displayName","name","syncUIComponentType","Symbol","singletonSyncUIRef","SyncUISingletonComp","props","push","input","RegisterSyncUI","map","SyncComp","key","_syncUIFactory"],"mappings":"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"}
|
package/dist/syncUI.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import React, { useEffect } from "react";
|
|
2
|
+
export declare const useComponentDidMount: (fn: Parameters<typeof useEffect>[0]) => void;
|
|
3
|
+
export declare const useAsyncQueue: <Data, ResolveValue = void>() => {
|
|
4
|
+
head: {
|
|
5
|
+
data: Data;
|
|
6
|
+
type: Symbol;
|
|
7
|
+
resolve: (value: ResolveValue) => void;
|
|
8
|
+
reject: (reason?: any) => void;
|
|
9
|
+
} | undefined;
|
|
10
|
+
registerToQueue: (type: Symbol, data: Data) => Promise<ResolveValue>;
|
|
11
|
+
};
|
|
12
|
+
export declare const syncUIFactory: () => {
|
|
13
|
+
makeSyncUI: <ArgData, ResolveValue = void>(SyncUserComp: React.FC<{
|
|
14
|
+
data: ArgData;
|
|
15
|
+
resolve: (value: ResolveValue) => void;
|
|
16
|
+
reject: (reason?: any) => void;
|
|
17
|
+
}>) => (input: ArgData) => Promise<ResolveValue>;
|
|
18
|
+
RegisterSyncUI: () => JSX.Element;
|
|
19
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "react-sync-ui",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"repository": "https://github.com/Svehla/react-sync-ui",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "Jakub Švehla",
|
|
7
|
+
"main": "dist/index.js",
|
|
8
|
+
"module": "dist/index.esm.js",
|
|
9
|
+
"typings": "dist/index.d.ts",
|
|
10
|
+
"files": [
|
|
11
|
+
"dist",
|
|
12
|
+
"src"
|
|
13
|
+
],
|
|
14
|
+
"scripts": {
|
|
15
|
+
"analyze": "size-limit --why",
|
|
16
|
+
"build": "tsdx build",
|
|
17
|
+
"lint": "tsdx lint",
|
|
18
|
+
"lint:fix": "tsdx lint --fix",
|
|
19
|
+
"prepare": "tsdx build",
|
|
20
|
+
"size": "size-limit",
|
|
21
|
+
"start": "tsdx watch",
|
|
22
|
+
"test": "tsdx test --passWithNoTests",
|
|
23
|
+
"test:watch": "tsdx test --passWithNoTests --watchAll"
|
|
24
|
+
},
|
|
25
|
+
"husky": {
|
|
26
|
+
"hooks": {
|
|
27
|
+
"pre-commit": "tsdx lint"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@size-limit/preset-small-lib": "^5.0.5",
|
|
32
|
+
"@testing-library/react-hooks": "^7.0.2",
|
|
33
|
+
"@types/react": "^17.0.27",
|
|
34
|
+
"@types/react-dom": "^17.0.9",
|
|
35
|
+
"@typescript-eslint/parser": "^4.33.0",
|
|
36
|
+
"eslint-config-react-app": "^6.0.0",
|
|
37
|
+
"eslint-plugin-react": "^7.31.10",
|
|
38
|
+
"eslint-plugin-sort-imports-es6-autofix": "^0.6.0",
|
|
39
|
+
"husky": "^7.0.2",
|
|
40
|
+
"react": "^17.0.2",
|
|
41
|
+
"react-dom": "^17.0.2",
|
|
42
|
+
"size-limit": "^5.0.5",
|
|
43
|
+
"tsdx": "^0.14.1",
|
|
44
|
+
"tslib": "^2.3.1",
|
|
45
|
+
"typescript": "^4.8.3"
|
|
46
|
+
},
|
|
47
|
+
"peerDependencies": {
|
|
48
|
+
"react": ">=16"
|
|
49
|
+
},
|
|
50
|
+
"engines": {
|
|
51
|
+
"node": ">=10"
|
|
52
|
+
},
|
|
53
|
+
"size-limit": []
|
|
54
|
+
}
|
package/src/index.ts
ADDED
package/src/syncUI.tsx
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import React, { useCallback, useEffect, useState } from "react";
|
|
2
|
+
|
|
3
|
+
export const useComponentDidMount = (fn: Parameters<typeof useEffect>[0]) => {
|
|
4
|
+
useEffect(fn, []);
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
const getSingletonCompCheck = (errorMsg: string) => {
|
|
8
|
+
let globalMountCounter = 0;
|
|
9
|
+
|
|
10
|
+
return () => {
|
|
11
|
+
useComponentDidMount(() => {
|
|
12
|
+
if (globalMountCounter > 0) throw new Error(errorMsg);
|
|
13
|
+
globalMountCounter++;
|
|
14
|
+
});
|
|
15
|
+
return <React.Fragment />;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
// TODO: add docs + add tests
|
|
20
|
+
export const useAsyncQueue = <Data, ResolveValue = void>() => {
|
|
21
|
+
const [asyncQueue, setAsyncQueue] = useState(
|
|
22
|
+
[] as {
|
|
23
|
+
// TODO: rename type into typeId
|
|
24
|
+
type: Symbol;
|
|
25
|
+
data: Data;
|
|
26
|
+
resolve: (arg: ResolveValue) => void;
|
|
27
|
+
reject: (arg: any) => void;
|
|
28
|
+
}[]
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
const registerToQueue = useCallback((type: Symbol, data: Data) => {
|
|
32
|
+
return new Promise<ResolveValue>((resolve, reject) => setAsyncQueue(p => [...p, { type, data, resolve, reject }]));
|
|
33
|
+
}, []);
|
|
34
|
+
|
|
35
|
+
const resolveHeadItem = useCallback((value: ResolveValue) => {
|
|
36
|
+
setAsyncQueue(queue => {
|
|
37
|
+
const [first, ...rest] = queue;
|
|
38
|
+
first?.resolve(value);
|
|
39
|
+
return rest;
|
|
40
|
+
});
|
|
41
|
+
}, []);
|
|
42
|
+
|
|
43
|
+
const rejectHeadItem = useCallback((reason?: any) => {
|
|
44
|
+
setAsyncQueue(queue => {
|
|
45
|
+
const [first, ...rest] = queue;
|
|
46
|
+
first?.reject(reason);
|
|
47
|
+
return rest;
|
|
48
|
+
});
|
|
49
|
+
}, []);
|
|
50
|
+
|
|
51
|
+
return {
|
|
52
|
+
head: asyncQueue[0]
|
|
53
|
+
? {
|
|
54
|
+
data: asyncQueue[0]?.data,
|
|
55
|
+
type: asyncQueue[0]?.type,
|
|
56
|
+
resolve: resolveHeadItem,
|
|
57
|
+
reject: rejectHeadItem
|
|
58
|
+
}
|
|
59
|
+
: undefined,
|
|
60
|
+
registerToQueue
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
// https://github.com/jaredpalmer/tsdx/issues/200???
|
|
64
|
+
// TODO: there is tsdx old typescript parser and new ts fancy syntax is not working...
|
|
65
|
+
// type QueueItem<Data, ResolveValue> = ReturnType<typeof useAsyncQueue<any, any>>
|
|
66
|
+
type QueueItem<Data, ResolveValue> = {
|
|
67
|
+
head:
|
|
68
|
+
| {
|
|
69
|
+
data: Data;
|
|
70
|
+
type: Symbol;
|
|
71
|
+
resolve: (value: ResolveValue) => void;
|
|
72
|
+
reject: (reason?: any) => void;
|
|
73
|
+
}
|
|
74
|
+
| undefined;
|
|
75
|
+
registerToQueue: (type: Symbol, data: Data) => Promise<ResolveValue>;
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
export const syncUIFactory = () => {
|
|
79
|
+
const mutSyncUIComponentsRenderQueue = [] as React.FC<QueueItem<any, any>>[];
|
|
80
|
+
|
|
81
|
+
const ThrowIfMoreInstances = getSingletonCompCheck("You have to init <RegisterSyncUI /> just one time");
|
|
82
|
+
|
|
83
|
+
return {
|
|
84
|
+
makeSyncUI: <ArgData, ResolveValue = void>(
|
|
85
|
+
SyncUserComp: React.FC<{
|
|
86
|
+
data: ArgData;
|
|
87
|
+
resolve: (value: ResolveValue) => void;
|
|
88
|
+
reject: (reason?: any) => void;
|
|
89
|
+
}>
|
|
90
|
+
) => {
|
|
91
|
+
const _debugName = SyncUserComp.displayName ?? SyncUserComp.name ?? "uniqSymbolMessageType";
|
|
92
|
+
|
|
93
|
+
const syncUIComponentType = Symbol(_debugName);
|
|
94
|
+
|
|
95
|
+
// object with the registerToQueue key has to be there to change returned mutable reference object while the function is already called
|
|
96
|
+
const singletonSyncUIRef = {
|
|
97
|
+
registerToQueue: undefined as undefined | QueueItem<ArgData, ResolveValue>["registerToQueue"]
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
const SyncUISingletonComp = (props: QueueItem<ArgData, ResolveValue>) => {
|
|
101
|
+
useComponentDidMount(() => {
|
|
102
|
+
singletonSyncUIRef.registerToQueue = props.registerToQueue;
|
|
103
|
+
return () => (singletonSyncUIRef.registerToQueue = undefined);
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
if (!props.head) return null;
|
|
107
|
+
if (props.head.type !== syncUIComponentType) return null;
|
|
108
|
+
|
|
109
|
+
return <SyncUserComp data={props.head.data} resolve={props.head.resolve} reject={props.head.reject} />;
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
mutSyncUIComponentsRenderQueue.push(SyncUISingletonComp);
|
|
113
|
+
|
|
114
|
+
return (input: ArgData) => {
|
|
115
|
+
if (!singletonSyncUIRef.registerToQueue) throw new Error(`You have to initialize <RegisterSyncUI />`);
|
|
116
|
+
return singletonSyncUIRef.registerToQueue(syncUIComponentType, input);
|
|
117
|
+
};
|
|
118
|
+
},
|
|
119
|
+
RegisterSyncUI: () => {
|
|
120
|
+
const queue = useAsyncQueue();
|
|
121
|
+
return (
|
|
122
|
+
<>
|
|
123
|
+
<ThrowIfMoreInstances />
|
|
124
|
+
{mutSyncUIComponentsRenderQueue.map((SyncComp, key) => (
|
|
125
|
+
<React.Fragment key={key}>
|
|
126
|
+
<SyncComp {...queue} />
|
|
127
|
+
</React.Fragment>
|
|
128
|
+
))}
|
|
129
|
+
</>
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
};
|