react-sync-ui 0.1.5 → 1.0.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 +43 -2
- package/dist/index.d.ts +6 -6
- package/dist/react-sync-ui.cjs.development.js +9 -14
- package/dist/react-sync-ui.cjs.development.js.map +1 -1
- package/dist/react-sync-ui.cjs.production.min.js +1 -1
- package/dist/react-sync-ui.cjs.production.min.js.map +1 -1
- package/dist/react-sync-ui.esm.js +9 -14
- package/dist/react-sync-ui.esm.js.map +1 -1
- package/dist/syncUI.d.ts +1 -2
- package/package.json +1 -1
- package/src/syncUI.tsx +6 -2
package/README.md
CHANGED
|
@@ -8,6 +8,30 @@
|
|
|
8
8
|
<button
|
|
9
9
|
onClick={async () => {
|
|
10
10
|
// call synchronous UI workflow with promisified React components
|
|
11
|
+
|
|
12
|
+
const likeSyncUI = await syncConfirm("Do you like this library?");
|
|
13
|
+
|
|
14
|
+
if (likeSyncUI) {
|
|
15
|
+
await syncAlert("Thanks, we like you too");
|
|
16
|
+
} else {
|
|
17
|
+
const isUserSure = await syncConfirm("Are you sure?");
|
|
18
|
+
if (isUserSure) {
|
|
19
|
+
await syncAlert("Try to give it a second try");
|
|
20
|
+
} else {
|
|
21
|
+
await syncAlert("Thanks, we like you too");
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}}
|
|
25
|
+
>
|
|
26
|
+
Run
|
|
27
|
+
</button>
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+

|
|
31
|
+
|
|
32
|
+
```tsx
|
|
33
|
+
<button
|
|
34
|
+
onClick={async () => {
|
|
11
35
|
const name = await syncPrompt("Fill your name");
|
|
12
36
|
|
|
13
37
|
while ((await syncPrompt(`Fill your password!`)) !== "1234") {
|
|
@@ -21,7 +45,7 @@
|
|
|
21
45
|
</button>
|
|
22
46
|
```
|
|
23
47
|
|
|
24
|
-

|
|
25
49
|
|
|
26
50
|
`react-sync-ui` provides function `makeSyncUI<InputData, ResolveValue>` which transform your declarative React Components
|
|
27
51
|
into the promisified awaitable functions.
|
|
@@ -55,7 +79,7 @@ Thanks to `react-sync-ui` you can simply promisify your React Components UI and
|
|
|
55
79
|
|
|
56
80
|
And that's why `react-sync-ui` was created. ❤
|
|
57
81
|
|
|
58
|
-
PS:
|
|
82
|
+
PS: I took inspiration from awesome functions: `window.alert`, `window.confirm` and `window.prompt`.
|
|
59
83
|
|
|
60
84
|
## Installation
|
|
61
85
|
|
|
@@ -215,3 +239,20 @@ export const syncConfirm = makeSyncUI<
|
|
|
215
239
|
click to me
|
|
216
240
|
</button>;
|
|
217
241
|
```
|
|
242
|
+
|
|
243
|
+
## Advance use-case, Multiple async queues
|
|
244
|
+
|
|
245
|
+
You're able to initialized multiple independent instances of `react-sync-ui` queue.
|
|
246
|
+
|
|
247
|
+
Multiple instances are made by `xxx`
|
|
248
|
+
|
|
249
|
+
```tsx
|
|
250
|
+
import { syncUIFactory } from "react-sync-ui";
|
|
251
|
+
|
|
252
|
+
export const syncUI1 = syncUIFactory();
|
|
253
|
+
export const syncUI2 = syncUIFactory();
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
You may check the full multiple queue example here
|
|
257
|
+
|
|
258
|
+
[react-sync-ui/example/MultiQueuesApp.tsx](https://github.com/Svehla/react-sync-ui/blob/main/example/MultiQueuesApp.tsx)
|
package/dist/index.d.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
2
|
export declare const syncUIFactory: () => {
|
|
3
|
-
makeSyncUI: <
|
|
4
|
-
data:
|
|
3
|
+
makeSyncUI: <InputData, ResolveValue = void>(SyncUIUserComp: import("react").FC<{
|
|
4
|
+
data: InputData;
|
|
5
5
|
resolve: (value: ResolveValue) => void;
|
|
6
6
|
reject: (reason?: any) => void;
|
|
7
|
-
}>) => (input:
|
|
7
|
+
}>) => (input: InputData) => Promise<ResolveValue>;
|
|
8
8
|
SyncUI: () => JSX.Element;
|
|
9
9
|
};
|
|
10
|
-
export declare const makeSyncUI: <
|
|
11
|
-
data:
|
|
10
|
+
export declare const makeSyncUI: <InputData, ResolveValue = void>(SyncUIUserComp: import("react").FC<{
|
|
11
|
+
data: InputData;
|
|
12
12
|
resolve: (value: ResolveValue) => void;
|
|
13
13
|
reject: (reason?: any) => void;
|
|
14
|
-
}>) => (input:
|
|
14
|
+
}>) => (input: InputData) => Promise<ResolveValue>, SyncUI: () => JSX.Element;
|
|
@@ -9,18 +9,7 @@ var React__default = _interopDefault(React);
|
|
|
9
9
|
|
|
10
10
|
var useComponentDidMount = function useComponentDidMount(fn) {
|
|
11
11
|
React.useEffect(fn, []);
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
var getSingletonComponentCheck = function getSingletonComponentCheck(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
|
-
};
|
|
12
|
+
}; // this check broke the working of the hot reloading
|
|
24
13
|
|
|
25
14
|
var usePromiseQueue = function usePromiseQueue() {
|
|
26
15
|
var _asyncQueue$;
|
|
@@ -68,7 +57,13 @@ var usePromiseQueue = function usePromiseQueue() {
|
|
|
68
57
|
|
|
69
58
|
var syncUIFactory = function syncUIFactory() {
|
|
70
59
|
var mutSyncUIComponentsRenderQueue = [];
|
|
71
|
-
|
|
60
|
+
/*
|
|
61
|
+
// this check broke the working of the hot reloading
|
|
62
|
+
const ThrowIfMoreInstances = getSingletonComponentCheck(
|
|
63
|
+
"<SyncUI /> has to be initialized only once"
|
|
64
|
+
);
|
|
65
|
+
*/
|
|
66
|
+
|
|
72
67
|
return {
|
|
73
68
|
makeSyncUI: function makeSyncUI(SyncUIUserComp) {
|
|
74
69
|
var _ref, _SyncUIUserComp$displ;
|
|
@@ -108,7 +103,7 @@ var syncUIFactory = function syncUIFactory() {
|
|
|
108
103
|
},
|
|
109
104
|
SyncUI: function SyncUI() {
|
|
110
105
|
var queue = usePromiseQueue();
|
|
111
|
-
return React__default.createElement(React__default.Fragment, null,
|
|
106
|
+
return React__default.createElement(React__default.Fragment, null, mutSyncUIComponentsRenderQueue.map(function (SyncComp, key) {
|
|
112
107
|
return React__default.createElement(React__default.Fragment, {
|
|
113
108
|
key: key
|
|
114
109
|
}, React__default.createElement(SyncComp, Object.assign({}, queue)));
|
|
@@ -1 +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\
|
|
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\nconst useComponentDidMount = (fn: Parameters<typeof useEffect>[0]) => {\n useEffect(fn, []);\n};\n\n// this check broke the working of the hot reloading\nconst getSingletonComponentCheck = (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// ------------------------------------------------------------------------------------\n// TODO: there is tsdx old typescript parser and new ts fancy syntax is not working...\n// https://github.com/jaredpalmer/tsdx/issues/200\n// type PromiseQueueAPI<Data, ResolveValue> = ReturnType<typeof usePromiseQueue<any, any>>\ntype PromiseQueueAPI<Data, ResolveValue> = {\n head?: {\n data: Data;\n resolve: (value: ResolveValue) => void;\n reject: (reason?: any) => void;\n };\n push: (data: Data) => Promise<ResolveValue>;\n};\n\nexport const usePromiseQueue = <Data, ResolveValue = void>(): PromiseQueueAPI<\n Data,\n ResolveValue\n> => {\n const [asyncQueue, setAsyncQueue] = useState(\n [] as {\n data: Data;\n resolve: (arg: ResolveValue) => void;\n reject: (arg: any) => void;\n }[]\n );\n\n const push = useCallback((data: Data) => {\n return new Promise<ResolveValue>((resolve, reject) =>\n setAsyncQueue(p => [...p, { data, resolve, reject }])\n );\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 resolve: resolveHeadItem,\n reject: rejectHeadItem\n }\n : undefined,\n push\n };\n};\n\n// ------------------------------------------------------------------------------------\n\nexport const syncUIFactory = () => {\n const mutSyncUIComponentsRenderQueue = [] as React.FC<\n PromiseQueueAPI<any, any>\n >[];\n\n /*\n // this check broke the working of the hot reloading\n const ThrowIfMoreInstances = getSingletonComponentCheck(\n \"<SyncUI /> has to be initialized only once\"\n );\n */\n\n return {\n makeSyncUI: <InputData, ResolveValue = void>(\n SyncUIUserComp: React.FC<{\n data: InputData;\n resolve: (value: ResolveValue) => void;\n reject: (reason?: any) => void;\n }>\n ) => {\n type QItem = PromiseQueueAPI<\n { type: Symbol; inputData: InputData },\n ResolveValue\n >;\n\n const _debugName =\n SyncUIUserComp.displayName ??\n SyncUIUserComp.name ??\n \"uniqSymbolMessageType\";\n\n const syncUIComponentType = Symbol(_debugName);\n\n // object pointer reference with the push key has to be there to change returned mutable reference object while the function is already called\n const singletonSyncUIRef = {\n push: undefined as undefined | QItem[\"push\"]\n };\n\n const SyncUISingletonComponent = (props: QItem) => {\n useComponentDidMount(() => {\n singletonSyncUIRef.push = props.push;\n return () => (singletonSyncUIRef.push = undefined);\n });\n\n if (!props.head) return null;\n if (props.head.data.type !== syncUIComponentType) return null;\n\n return (\n <SyncUIUserComp\n data={props.head.data.inputData}\n resolve={props.head.resolve}\n reject={props.head.reject}\n />\n );\n };\n\n mutSyncUIComponentsRenderQueue.push(SyncUISingletonComponent);\n\n return (input: InputData) => {\n if (!singletonSyncUIRef.push)\n throw new Error(`You have to initialize <SyncUI />`);\n return singletonSyncUIRef.push({\n type: syncUIComponentType,\n inputData: input\n });\n };\n },\n SyncUI: () => {\n const queue = usePromiseQueue();\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, SyncUI } = syncUIFactory();\n"],"names":["useComponentDidMount","fn","useEffect","usePromiseQueue","useState","asyncQueue","setAsyncQueue","push","useCallback","data","Promise","resolve","reject","p","resolveHeadItem","value","queue","first","rest","rejectHeadItem","reason","head","undefined","syncUIFactory","mutSyncUIComponentsRenderQueue","makeSyncUI","SyncUIUserComp","_debugName","displayName","name","syncUIComponentType","Symbol","singletonSyncUIRef","SyncUISingletonComponent","props","type","React","inputData","input","Error","SyncUI","map","SyncComp","key","Fragment","_syncUIFactory"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e,
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e,t=require("react"),n=(e=t)&&"object"==typeof e&&"default"in e?e.default:e,r=function(){var e=[];return{makeSyncUI:function(r){var u,a,c=null!=(u=null!=(a=r.displayName)?a:r.name)?u:"uniqSymbolMessageType",l=Symbol(c),o={push:void 0};return e.push((function(e){return t.useEffect((function(){return o.push=e.push,function(){return o.push=void 0}}),[]),e.head?e.head.data.type!==l?null:n.createElement(r,{data:e.head.data.inputData,resolve:e.head.resolve,reject:e.head.reject}):null})),function(e){if(!o.push)throw new Error("You have to initialize <SyncUI />");return o.push({type:l,inputData:e})}},SyncUI:function(){var r,u,a,c,l,o,i,s=(a=(u=t.useState([]))[0],c=u[1],l=t.useCallback((function(e){return new Promise((function(t,n){return c((function(r){return[].concat(r,[{data:e,resolve:t,reject:n}])}))}))}),[]),o=t.useCallback((function(e){c((function(t){var n=t[0],r=t.slice(1);return null==n||n.resolve(e),r}))}),[]),i=t.useCallback((function(e){c((function(t){var n=t[0],r=t.slice(1);return null==n||n.reject(e),r}))}),[]),{head:a[0]?{data:null==(r=a[0])?void 0:r.data,resolve:o,reject:i}:void 0,push:l});return n.createElement(n.Fragment,null,e.map((function(e,t){return n.createElement(n.Fragment,{key:t},n.createElement(e,Object.assign({},s)))})))}}},u=r(),a=u.makeSyncUI;exports.SyncUI=u.SyncUI,exports.makeSyncUI=a,exports.syncUIFactory=r;
|
|
2
2
|
//# sourceMappingURL=react-sync-ui.cjs.production.min.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"react-sync-ui.cjs.production.min.js","sources":["../src/
|
|
1
|
+
{"version":3,"file":"react-sync-ui.cjs.production.min.js","sources":["../src/index.ts","../src/syncUI.tsx"],"sourcesContent":["import { syncUIFactory as _syncUIFactory } from \"./syncUI\";\nexport const syncUIFactory = _syncUIFactory;\nexport const { makeSyncUI, SyncUI } = syncUIFactory();\n","import React, { useCallback, useEffect, useState } from \"react\";\n\nconst useComponentDidMount = (fn: Parameters<typeof useEffect>[0]) => {\n useEffect(fn, []);\n};\n\n// this check broke the working of the hot reloading\nconst getSingletonComponentCheck = (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// ------------------------------------------------------------------------------------\n// TODO: there is tsdx old typescript parser and new ts fancy syntax is not working...\n// https://github.com/jaredpalmer/tsdx/issues/200\n// type PromiseQueueAPI<Data, ResolveValue> = ReturnType<typeof usePromiseQueue<any, any>>\ntype PromiseQueueAPI<Data, ResolveValue> = {\n head?: {\n data: Data;\n resolve: (value: ResolveValue) => void;\n reject: (reason?: any) => void;\n };\n push: (data: Data) => Promise<ResolveValue>;\n};\n\nexport const usePromiseQueue = <Data, ResolveValue = void>(): PromiseQueueAPI<\n Data,\n ResolveValue\n> => {\n const [asyncQueue, setAsyncQueue] = useState(\n [] as {\n data: Data;\n resolve: (arg: ResolveValue) => void;\n reject: (arg: any) => void;\n }[]\n );\n\n const push = useCallback((data: Data) => {\n return new Promise<ResolveValue>((resolve, reject) =>\n setAsyncQueue(p => [...p, { data, resolve, reject }])\n );\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 resolve: resolveHeadItem,\n reject: rejectHeadItem\n }\n : undefined,\n push\n };\n};\n\n// ------------------------------------------------------------------------------------\n\nexport const syncUIFactory = () => {\n const mutSyncUIComponentsRenderQueue = [] as React.FC<\n PromiseQueueAPI<any, any>\n >[];\n\n /*\n // this check broke the working of the hot reloading\n const ThrowIfMoreInstances = getSingletonComponentCheck(\n \"<SyncUI /> has to be initialized only once\"\n );\n */\n\n return {\n makeSyncUI: <InputData, ResolveValue = void>(\n SyncUIUserComp: React.FC<{\n data: InputData;\n resolve: (value: ResolveValue) => void;\n reject: (reason?: any) => void;\n }>\n ) => {\n type QItem = PromiseQueueAPI<\n { type: Symbol; inputData: InputData },\n ResolveValue\n >;\n\n const _debugName =\n SyncUIUserComp.displayName ??\n SyncUIUserComp.name ??\n \"uniqSymbolMessageType\";\n\n const syncUIComponentType = Symbol(_debugName);\n\n // object pointer reference with the push key has to be there to change returned mutable reference object while the function is already called\n const singletonSyncUIRef = {\n push: undefined as undefined | QItem[\"push\"]\n };\n\n const SyncUISingletonComponent = (props: QItem) => {\n useComponentDidMount(() => {\n singletonSyncUIRef.push = props.push;\n return () => (singletonSyncUIRef.push = undefined);\n });\n\n if (!props.head) return null;\n if (props.head.data.type !== syncUIComponentType) return null;\n\n return (\n <SyncUIUserComp\n data={props.head.data.inputData}\n resolve={props.head.resolve}\n reject={props.head.reject}\n />\n );\n };\n\n mutSyncUIComponentsRenderQueue.push(SyncUISingletonComponent);\n\n return (input: InputData) => {\n if (!singletonSyncUIRef.push)\n throw new Error(`You have to initialize <SyncUI />`);\n return singletonSyncUIRef.push({\n type: syncUIComponentType,\n inputData: input\n });\n };\n },\n SyncUI: () => {\n const queue = usePromiseQueue();\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"],"names":["syncUIFactory","mutSyncUIComponentsRenderQueue","makeSyncUI","SyncUIUserComp","_debugName","displayName","name","syncUIComponentType","Symbol","singletonSyncUIRef","push","undefined","props","useEffect","head","data","type","React","inputData","resolve","reject","input","Error","SyncUI","asyncQueue","setAsyncQueue","resolveHeadItem","rejectHeadItem","queue","useState","useCallback","Promise","p","value","first","rest","reason","_asyncQueue$","map","SyncComp","key","Fragment"],"mappings":"oJACaA,EC+EgB,eACrBC,EAAiC,SAWhC,CACLC,WAAY,SACVC,WAWMC,oBACJD,EAAeE,eACfF,EAAeG,QACf,wBAEIC,EAAsBC,OAAOJ,GAG7BK,EAAqB,CACzBC,UAAMC,UAqBRV,EAA+BS,MAlBE,SAACE,UAlHtCC,aAmH2B,kBACnBJ,EAAmBC,KAAOE,EAAMF,KACzB,kBAAOD,EAAmBC,UAAOC,KArHlC,IAwHHC,EAAME,KACPF,EAAME,KAAKC,KAAKC,OAAST,EAA4B,KAGvDU,gBAACd,GACCY,KAAMH,EAAME,KAAKC,KAAKG,UACtBC,QAASP,EAAME,KAAKK,QACpBC,OAAQR,EAAME,KAAKM,SAPC,QAcnB,SAACC,OACDZ,EAAmBC,KACtB,MAAM,IAAIY,kDACLb,EAAmBC,KAAK,CAC7BM,KAAMT,EACNW,UAAWG,MAIjBE,OAAQ,mBA9GHC,EAAYC,EAQbf,EAMAgB,EAQAC,EAyFIC,GA/GHJ,KAA6BK,WAClC,QADiBJ,OAQbf,EAAOoB,eAAY,SAACf,UACjB,IAAIgB,SAAsB,SAACZ,EAASC,UACzCK,GAAc,SAAAO,mBAASA,GAAG,CAAEjB,KAAAA,EAAMI,QAAAA,EAASC,OAAAA,aAE5C,IAEGM,EAAkBI,eAAY,SAACG,GACnCR,GAAc,SAAAG,OACLM,EAAkBN,KAARO,EAAQP,wBACzBM,GAAAA,EAAOf,QAAQc,GACRE,OAER,IAEGR,EAAiBG,eAAY,SAACM,GAClCX,GAAc,SAAAG,OACLM,EAAkBN,KAARO,EAAQP,wBACzBM,GAAAA,EAAOd,OAAOgB,GACPD,OAER,IAEI,CACLrB,KAAMU,EAAW,GACb,CACET,cAAMS,EAAW,WAAXa,EAAetB,KACrBI,QAASO,EACTN,OAAQO,QAEVhB,EACJD,KAAAA,WA2EIO,gCAEGhB,EAA+BqC,KAAI,SAACC,EAAUC,UAC7CvB,gBAACA,EAAMwB,UAASD,IAAKA,GACnBvB,gBAACsB,mBAAaX,cDvJU5B,IAAvBE,IAAAA,4BAAYqB"}
|
|
@@ -2,18 +2,7 @@ import React, { useState, useCallback, useEffect } from 'react';
|
|
|
2
2
|
|
|
3
3
|
var useComponentDidMount = function useComponentDidMount(fn) {
|
|
4
4
|
useEffect(fn, []);
|
|
5
|
-
};
|
|
6
|
-
|
|
7
|
-
var getSingletonComponentCheck = function getSingletonComponentCheck(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
|
-
};
|
|
5
|
+
}; // this check broke the working of the hot reloading
|
|
17
6
|
|
|
18
7
|
var usePromiseQueue = function usePromiseQueue() {
|
|
19
8
|
var _asyncQueue$;
|
|
@@ -61,7 +50,13 @@ var usePromiseQueue = function usePromiseQueue() {
|
|
|
61
50
|
|
|
62
51
|
var syncUIFactory = function syncUIFactory() {
|
|
63
52
|
var mutSyncUIComponentsRenderQueue = [];
|
|
64
|
-
|
|
53
|
+
/*
|
|
54
|
+
// this check broke the working of the hot reloading
|
|
55
|
+
const ThrowIfMoreInstances = getSingletonComponentCheck(
|
|
56
|
+
"<SyncUI /> has to be initialized only once"
|
|
57
|
+
);
|
|
58
|
+
*/
|
|
59
|
+
|
|
65
60
|
return {
|
|
66
61
|
makeSyncUI: function makeSyncUI(SyncUIUserComp) {
|
|
67
62
|
var _ref, _SyncUIUserComp$displ;
|
|
@@ -101,7 +96,7 @@ var syncUIFactory = function syncUIFactory() {
|
|
|
101
96
|
},
|
|
102
97
|
SyncUI: function SyncUI() {
|
|
103
98
|
var queue = usePromiseQueue();
|
|
104
|
-
return React.createElement(React.Fragment, null,
|
|
99
|
+
return React.createElement(React.Fragment, null, mutSyncUIComponentsRenderQueue.map(function (SyncComp, key) {
|
|
105
100
|
return React.createElement(React.Fragment, {
|
|
106
101
|
key: key
|
|
107
102
|
}, React.createElement(SyncComp, Object.assign({}, queue)));
|
|
@@ -1 +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\
|
|
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\nconst useComponentDidMount = (fn: Parameters<typeof useEffect>[0]) => {\n useEffect(fn, []);\n};\n\n// this check broke the working of the hot reloading\nconst getSingletonComponentCheck = (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// ------------------------------------------------------------------------------------\n// TODO: there is tsdx old typescript parser and new ts fancy syntax is not working...\n// https://github.com/jaredpalmer/tsdx/issues/200\n// type PromiseQueueAPI<Data, ResolveValue> = ReturnType<typeof usePromiseQueue<any, any>>\ntype PromiseQueueAPI<Data, ResolveValue> = {\n head?: {\n data: Data;\n resolve: (value: ResolveValue) => void;\n reject: (reason?: any) => void;\n };\n push: (data: Data) => Promise<ResolveValue>;\n};\n\nexport const usePromiseQueue = <Data, ResolveValue = void>(): PromiseQueueAPI<\n Data,\n ResolveValue\n> => {\n const [asyncQueue, setAsyncQueue] = useState(\n [] as {\n data: Data;\n resolve: (arg: ResolveValue) => void;\n reject: (arg: any) => void;\n }[]\n );\n\n const push = useCallback((data: Data) => {\n return new Promise<ResolveValue>((resolve, reject) =>\n setAsyncQueue(p => [...p, { data, resolve, reject }])\n );\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 resolve: resolveHeadItem,\n reject: rejectHeadItem\n }\n : undefined,\n push\n };\n};\n\n// ------------------------------------------------------------------------------------\n\nexport const syncUIFactory = () => {\n const mutSyncUIComponentsRenderQueue = [] as React.FC<\n PromiseQueueAPI<any, any>\n >[];\n\n /*\n // this check broke the working of the hot reloading\n const ThrowIfMoreInstances = getSingletonComponentCheck(\n \"<SyncUI /> has to be initialized only once\"\n );\n */\n\n return {\n makeSyncUI: <InputData, ResolveValue = void>(\n SyncUIUserComp: React.FC<{\n data: InputData;\n resolve: (value: ResolveValue) => void;\n reject: (reason?: any) => void;\n }>\n ) => {\n type QItem = PromiseQueueAPI<\n { type: Symbol; inputData: InputData },\n ResolveValue\n >;\n\n const _debugName =\n SyncUIUserComp.displayName ??\n SyncUIUserComp.name ??\n \"uniqSymbolMessageType\";\n\n const syncUIComponentType = Symbol(_debugName);\n\n // object pointer reference with the push key has to be there to change returned mutable reference object while the function is already called\n const singletonSyncUIRef = {\n push: undefined as undefined | QItem[\"push\"]\n };\n\n const SyncUISingletonComponent = (props: QItem) => {\n useComponentDidMount(() => {\n singletonSyncUIRef.push = props.push;\n return () => (singletonSyncUIRef.push = undefined);\n });\n\n if (!props.head) return null;\n if (props.head.data.type !== syncUIComponentType) return null;\n\n return (\n <SyncUIUserComp\n data={props.head.data.inputData}\n resolve={props.head.resolve}\n reject={props.head.reject}\n />\n );\n };\n\n mutSyncUIComponentsRenderQueue.push(SyncUISingletonComponent);\n\n return (input: InputData) => {\n if (!singletonSyncUIRef.push)\n throw new Error(`You have to initialize <SyncUI />`);\n return singletonSyncUIRef.push({\n type: syncUIComponentType,\n inputData: input\n });\n };\n },\n SyncUI: () => {\n const queue = usePromiseQueue();\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, SyncUI } = syncUIFactory();\n"],"names":["useComponentDidMount","fn","useEffect","usePromiseQueue","useState","asyncQueue","setAsyncQueue","push","useCallback","data","Promise","resolve","reject","p","resolveHeadItem","value","queue","first","rest","rejectHeadItem","reason","head","undefined","syncUIFactory","mutSyncUIComponentsRenderQueue","makeSyncUI","SyncUIUserComp","_debugName","displayName","name","syncUIComponentType","Symbol","singletonSyncUIRef","SyncUISingletonComponent","props","type","React","inputData","input","Error","SyncUI","map","SyncComp","key","Fragment","_syncUIFactory"],"mappings":"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"}
|
package/dist/syncUI.d.ts
CHANGED
package/package.json
CHANGED
package/src/syncUI.tsx
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import React, { useCallback, useEffect, useState } from "react";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
const useComponentDidMount = (fn: Parameters<typeof useEffect>[0]) => {
|
|
4
4
|
useEffect(fn, []);
|
|
5
5
|
};
|
|
6
6
|
|
|
7
|
+
// this check broke the working of the hot reloading
|
|
7
8
|
const getSingletonComponentCheck = (errorMsg: string) => {
|
|
8
9
|
let globalMountCounter = 0;
|
|
9
10
|
|
|
@@ -82,9 +83,12 @@ export const syncUIFactory = () => {
|
|
|
82
83
|
PromiseQueueAPI<any, any>
|
|
83
84
|
>[];
|
|
84
85
|
|
|
86
|
+
/*
|
|
87
|
+
// this check broke the working of the hot reloading
|
|
85
88
|
const ThrowIfMoreInstances = getSingletonComponentCheck(
|
|
86
89
|
"<SyncUI /> has to be initialized only once"
|
|
87
90
|
);
|
|
91
|
+
*/
|
|
88
92
|
|
|
89
93
|
return {
|
|
90
94
|
makeSyncUI: <InputData, ResolveValue = void>(
|
|
@@ -144,7 +148,7 @@ export const syncUIFactory = () => {
|
|
|
144
148
|
const queue = usePromiseQueue();
|
|
145
149
|
return (
|
|
146
150
|
<>
|
|
147
|
-
<ThrowIfMoreInstances />
|
|
151
|
+
{/* <ThrowIfMoreInstances /> */}
|
|
148
152
|
{mutSyncUIComponentsRenderQueue.map((SyncComp, key) => (
|
|
149
153
|
<React.Fragment key={key}>
|
|
150
154
|
<SyncComp {...queue} />
|