@hairy/react-lib 1.24.0 → 1.26.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.cjs +95 -49
- package/dist/index.d.ts +46 -6
- package/dist/index.global.js +537 -445
- package/dist/index.js +84 -39
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -37,13 +37,14 @@ __export(index_exports, {
|
|
|
37
37
|
Injector: () => Injector,
|
|
38
38
|
Switch: () => Switch,
|
|
39
39
|
Then: () => Then,
|
|
40
|
-
|
|
40
|
+
Trigger: () => Trigger,
|
|
41
41
|
Unless: () => Unless,
|
|
42
42
|
cls: () => cls,
|
|
43
43
|
defineAsyncStore: () => defineAsyncStore,
|
|
44
44
|
defineStore: () => defineStore,
|
|
45
45
|
proxyWithPersistant: () => proxyWithPersistant,
|
|
46
|
-
ref: () =>
|
|
46
|
+
ref: () => ref2,
|
|
47
|
+
track: () => track,
|
|
47
48
|
useAsyncCallback: () => useAsyncCallback,
|
|
48
49
|
useAsyncState: () => useAsyncState,
|
|
49
50
|
useDebounce: () => useDebounce,
|
|
@@ -92,6 +93,51 @@ cls.append = function(value, newClass) {
|
|
|
92
93
|
return value ? `${value} ${newClass}` : newClass;
|
|
93
94
|
};
|
|
94
95
|
|
|
96
|
+
// ../util-core/src/util/noop.ts
|
|
97
|
+
var noop = () => {
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
// ../util-core/src/util/deferred.ts
|
|
101
|
+
var Deferred = class extends Promise {
|
|
102
|
+
resolve;
|
|
103
|
+
reject;
|
|
104
|
+
constructor(executor = noop) {
|
|
105
|
+
let _resolve, _reject;
|
|
106
|
+
super((resolve_, reject_) => {
|
|
107
|
+
_resolve = resolve_;
|
|
108
|
+
_reject = reject_;
|
|
109
|
+
return executor(resolve_, reject_);
|
|
110
|
+
});
|
|
111
|
+
this.resolve = (value) => {
|
|
112
|
+
_resolve(value);
|
|
113
|
+
return this;
|
|
114
|
+
};
|
|
115
|
+
this.reject = (reason) => {
|
|
116
|
+
_reject(reason);
|
|
117
|
+
return this;
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
// ../util-core/src/util/json.ts
|
|
123
|
+
function jsonTryParse(text) {
|
|
124
|
+
try {
|
|
125
|
+
return JSON.parse(text || "");
|
|
126
|
+
} catch {
|
|
127
|
+
return void 0;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// src/utils/track.ts
|
|
132
|
+
var import_valtio = require("valtio");
|
|
133
|
+
function track(fn, ...args) {
|
|
134
|
+
const deferred = (0, import_valtio.ref)(new Deferred());
|
|
135
|
+
const exposer = { fn, args, deferred, id: ++Trigger.id };
|
|
136
|
+
Trigger.tasks.set(exposer.id, exposer);
|
|
137
|
+
deferred.then(() => Trigger.tasks.delete(exposer.id));
|
|
138
|
+
return deferred;
|
|
139
|
+
}
|
|
140
|
+
|
|
95
141
|
// src/utils/wrapper.ts
|
|
96
142
|
var import_react = require("react");
|
|
97
143
|
function wrapper(tag, props, children) {
|
|
@@ -184,28 +230,36 @@ function repack(c) {
|
|
|
184
230
|
return c.component ? c : { component: c };
|
|
185
231
|
}
|
|
186
232
|
|
|
187
|
-
// src/components/utils/
|
|
188
|
-
var import_html_parse_stringify = __toESM(require("html-parse-stringify"), 1);
|
|
233
|
+
// src/components/utils/Trigger.ts
|
|
189
234
|
var import_react6 = require("react");
|
|
190
|
-
var
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
235
|
+
var import_valtio2 = require("valtio");
|
|
236
|
+
var import_utils8 = require("valtio/utils");
|
|
237
|
+
var pendingTasks = (0, import_utils8.proxyMap)();
|
|
238
|
+
function createTracker(exposer) {
|
|
239
|
+
const Component = () => {
|
|
240
|
+
try {
|
|
241
|
+
exposer.deferred.resolve(exposer.fn(...exposer.args));
|
|
242
|
+
} catch (error) {
|
|
243
|
+
exposer.deferred.reject(error);
|
|
244
|
+
}
|
|
245
|
+
return null;
|
|
246
|
+
};
|
|
247
|
+
Component.key = exposer.id;
|
|
248
|
+
return Component;
|
|
204
249
|
}
|
|
250
|
+
function renderTracker(Tracker) {
|
|
251
|
+
return (0, import_react6.createElement)(Tracker, { key: Tracker.key });
|
|
252
|
+
}
|
|
253
|
+
function Trigger() {
|
|
254
|
+
const values = [...(0, import_valtio2.useSnapshot)(pendingTasks).values()];
|
|
255
|
+
return values.map(createTracker).map(renderTracker);
|
|
256
|
+
}
|
|
257
|
+
Trigger.id = 0;
|
|
258
|
+
Trigger.tasks = pendingTasks;
|
|
205
259
|
|
|
206
260
|
// src/hooks/ref.ts
|
|
207
261
|
var import_react7 = require("react");
|
|
208
|
-
function
|
|
262
|
+
function ref2(value) {
|
|
209
263
|
function define(value2) {
|
|
210
264
|
if (typeof value2 === "function")
|
|
211
265
|
return (prev) => define(value2(prev.value));
|
|
@@ -215,8 +269,8 @@ function ref(value) {
|
|
|
215
269
|
enumerable: true
|
|
216
270
|
});
|
|
217
271
|
}
|
|
218
|
-
const [
|
|
219
|
-
return
|
|
272
|
+
const [ref3, set] = (0, import_react7.useState)(define(value));
|
|
273
|
+
return ref3;
|
|
220
274
|
}
|
|
221
275
|
|
|
222
276
|
// src/hooks/useAsyncCallback.ts
|
|
@@ -369,23 +423,14 @@ function useWhenever(source, cb, options) {
|
|
|
369
423
|
}
|
|
370
424
|
|
|
371
425
|
// src/storage/defineAsyncStore.ts
|
|
372
|
-
var
|
|
426
|
+
var import_utils10 = require("valtio/utils");
|
|
373
427
|
|
|
374
428
|
// src/storage/defineStore.ts
|
|
375
429
|
var import_react15 = require("react");
|
|
376
|
-
var
|
|
377
|
-
|
|
378
|
-
// ../util-core/src/util/json.ts
|
|
379
|
-
function jsonTryParse(text) {
|
|
380
|
-
try {
|
|
381
|
-
return JSON.parse(text || "");
|
|
382
|
-
} catch {
|
|
383
|
-
return void 0;
|
|
384
|
-
}
|
|
385
|
-
}
|
|
430
|
+
var import_valtio4 = require("valtio");
|
|
386
431
|
|
|
387
432
|
// src/storage/persistant.ts
|
|
388
|
-
var
|
|
433
|
+
var import_valtio3 = require("valtio");
|
|
389
434
|
function proxyWithPersistant(keyOrOptions, initialObject) {
|
|
390
435
|
let options;
|
|
391
436
|
if (typeof keyOrOptions === "string") {
|
|
@@ -395,8 +440,8 @@ function proxyWithPersistant(keyOrOptions, initialObject) {
|
|
|
395
440
|
}
|
|
396
441
|
const storage = options.storage || (typeof localStorage !== "undefined" ? localStorage : void 0);
|
|
397
442
|
typeof keyOrOptions === "string" && (keyOrOptions = { id: keyOrOptions });
|
|
398
|
-
const state = (0,
|
|
399
|
-
(0,
|
|
443
|
+
const state = (0, import_valtio3.proxy)(jsonTryParse(storage?.getItem(options.id)) || initialObject);
|
|
444
|
+
(0, import_valtio3.subscribe)(state, () => {
|
|
400
445
|
const pick = options.pick || Object.keys(state);
|
|
401
446
|
const statePick = {};
|
|
402
447
|
for (const key of pick)
|
|
@@ -415,18 +460,18 @@ function defineStore(store, options = {}) {
|
|
|
415
460
|
status.finished = false;
|
|
416
461
|
status.loading = false;
|
|
417
462
|
status.error = null;
|
|
418
|
-
const $status = (0,
|
|
419
|
-
const $state = options.persist ? proxyWithPersistant(options.persist, state) : (0,
|
|
463
|
+
const $status = (0, import_valtio4.proxy)(status);
|
|
464
|
+
const $state = options.persist ? proxyWithPersistant(options.persist, state) : (0, import_valtio4.proxy)(state);
|
|
420
465
|
const $actions = {};
|
|
421
466
|
const $getters = {};
|
|
422
467
|
setupActions($state, actions, $actions, $status);
|
|
423
468
|
setupGetters(state, $state, getters, $getters);
|
|
424
469
|
setupStatus($actions, $status);
|
|
425
470
|
function $subscribe(listener) {
|
|
426
|
-
return (0,
|
|
471
|
+
return (0, import_valtio4.subscribe)($state, () => listener($state));
|
|
427
472
|
}
|
|
428
473
|
$subscribe.status = function(listener) {
|
|
429
|
-
return (0,
|
|
474
|
+
return (0, import_valtio4.subscribe)($status, () => listener($status));
|
|
430
475
|
};
|
|
431
476
|
function $patch(patch) {
|
|
432
477
|
if (typeof patch === "function")
|
|
@@ -435,10 +480,10 @@ function defineStore(store, options = {}) {
|
|
|
435
480
|
Object.assign($state, patch);
|
|
436
481
|
}
|
|
437
482
|
function $signal(fn) {
|
|
438
|
-
return (0, import_react15.createElement)(() => fn((0,
|
|
483
|
+
return (0, import_react15.createElement)(() => fn((0, import_valtio4.useSnapshot)($state)));
|
|
439
484
|
}
|
|
440
485
|
$signal.status = function(fn) {
|
|
441
|
-
return (0, import_react15.createElement)(() => fn((0,
|
|
486
|
+
return (0, import_react15.createElement)(() => fn((0, import_valtio4.useSnapshot)($status)));
|
|
442
487
|
};
|
|
443
488
|
return {
|
|
444
489
|
$subscribe,
|
|
@@ -451,7 +496,7 @@ function defineStore(store, options = {}) {
|
|
|
451
496
|
...$actions
|
|
452
497
|
};
|
|
453
498
|
}
|
|
454
|
-
function
|
|
499
|
+
function track2(action, status) {
|
|
455
500
|
let loadings = 0;
|
|
456
501
|
const tracking = () => loadings++ === 0 && (status.loading = true);
|
|
457
502
|
const done = () => !--loadings && (status.loading = false);
|
|
@@ -478,7 +523,7 @@ function track(action, status) {
|
|
|
478
523
|
function setupActions($state, actions, $actions, $status) {
|
|
479
524
|
for (const key in actions) {
|
|
480
525
|
$status[key] = { finished: false, loading: false, error: null };
|
|
481
|
-
$actions[key] =
|
|
526
|
+
$actions[key] = track2(actions[key].bind($state), $status[key]);
|
|
482
527
|
}
|
|
483
528
|
}
|
|
484
529
|
function setupGetters(state, $state, getters, $getters) {
|
|
@@ -529,7 +574,7 @@ function defineAsyncStore(fetch, options = {}) {
|
|
|
529
574
|
},
|
|
530
575
|
{ persist: options.persist ? { id: options.persist, pick: ["value"] } : void 0 }
|
|
531
576
|
);
|
|
532
|
-
(0,
|
|
577
|
+
(0, import_utils10.watch)((get) => {
|
|
533
578
|
const status = get(store.$status.fetch);
|
|
534
579
|
store.$state.error = status.error;
|
|
535
580
|
store.$state.loading = status.loading;
|
|
@@ -540,15 +585,15 @@ function defineAsyncStore(fetch, options = {}) {
|
|
|
540
585
|
}
|
|
541
586
|
|
|
542
587
|
// src/storage/useStatus.tsx
|
|
543
|
-
var
|
|
588
|
+
var import_valtio5 = require("valtio");
|
|
544
589
|
function useStatus(store) {
|
|
545
|
-
return (0,
|
|
590
|
+
return (0, import_valtio5.useSnapshot)(store.$status);
|
|
546
591
|
}
|
|
547
592
|
|
|
548
593
|
// src/storage/useStore.ts
|
|
549
|
-
var
|
|
594
|
+
var import_valtio6 = require("valtio");
|
|
550
595
|
function useStore(store) {
|
|
551
|
-
return (0,
|
|
596
|
+
return (0, import_valtio6.useSnapshot)(store.$state);
|
|
552
597
|
}
|
|
553
598
|
// Annotate the CommonJS export names for ESM import in node:
|
|
554
599
|
0 && (module.exports = {
|
|
@@ -559,13 +604,14 @@ function useStore(store) {
|
|
|
559
604
|
Injector,
|
|
560
605
|
Switch,
|
|
561
606
|
Then,
|
|
562
|
-
|
|
607
|
+
Trigger,
|
|
563
608
|
Unless,
|
|
564
609
|
cls,
|
|
565
610
|
defineAsyncStore,
|
|
566
611
|
defineStore,
|
|
567
612
|
proxyWithPersistant,
|
|
568
613
|
ref,
|
|
614
|
+
track,
|
|
569
615
|
useAsyncCallback,
|
|
570
616
|
useAsyncState,
|
|
571
617
|
useDebounce,
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BooleanLike, PromiseFn, PromiseType
|
|
1
|
+
import { AnyFn, BooleanLike, Deferred, PromiseFn, PromiseType } from '@hairy/utils';
|
|
2
2
|
import * as react from 'react';
|
|
3
3
|
import { JSX, ReactNode, PropsWithChildren, ReactElement, FC, ComponentClass, SetStateAction, DetailedHTMLProps, HTMLAttributes } from 'react';
|
|
4
4
|
import * as valtio from 'valtio';
|
|
@@ -19,6 +19,18 @@ declare namespace cls {
|
|
|
19
19
|
var append: (value: any, newClass: any) => any;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
+
/**
|
|
23
|
+
* @requires `Trigger` component to be mounted in the tree.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```tsx
|
|
27
|
+
* // Obtain externally
|
|
28
|
+
* import { track } from '@hairy/lib-react'
|
|
29
|
+
* const context = await track(() => useContext(YourContext))
|
|
30
|
+
* console.log(context) // { ... }
|
|
31
|
+
*/
|
|
32
|
+
declare function track<T extends AnyFn>(fn: T, ...args: Parameters<T>): Promise<ReturnType<T>>;
|
|
33
|
+
|
|
22
34
|
type WrapperTag = keyof JSX.IntrinsicElements | Function;
|
|
23
35
|
type WrapperProps<Kag extends keyof JSX.IntrinsicElements | React.FC | unknown> = {
|
|
24
36
|
tag?: Kag;
|
|
@@ -73,11 +85,39 @@ interface InjectorProps {
|
|
|
73
85
|
}
|
|
74
86
|
declare function Injector(props: InjectorProps): ReactNode;
|
|
75
87
|
|
|
76
|
-
interface
|
|
77
|
-
|
|
78
|
-
|
|
88
|
+
interface Exposer {
|
|
89
|
+
deferred: Deferred<any>;
|
|
90
|
+
args: any[];
|
|
91
|
+
fn: AnyFn;
|
|
92
|
+
id: number;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* @example
|
|
96
|
+
* ```tsx
|
|
97
|
+
* import { Trigger } from '@hairy/lib-react'
|
|
98
|
+
*
|
|
99
|
+
* // Use triggers to capture context
|
|
100
|
+
* function App() {
|
|
101
|
+
* return (
|
|
102
|
+
* <YourContext.Provider>
|
|
103
|
+
* <Trigger />
|
|
104
|
+
* </YourContext.Provider>
|
|
105
|
+
* )
|
|
106
|
+
* }
|
|
107
|
+
*
|
|
108
|
+
* // Obtain externally
|
|
109
|
+
* import { track } from '@hairy/lib-react'
|
|
110
|
+
* const context = await track(() => useContext(YourContext))
|
|
111
|
+
* console.log(context) // { ... }
|
|
112
|
+
* ```
|
|
113
|
+
*/
|
|
114
|
+
declare function Trigger(): ReactNode[];
|
|
115
|
+
declare namespace Trigger {
|
|
116
|
+
var id: number;
|
|
117
|
+
var tasks: Map<number, Exposer> & {
|
|
118
|
+
$$valtioSnapshot: Omit<Map<number, Exposer>, "set" | "delete" | "clear">;
|
|
119
|
+
};
|
|
79
120
|
}
|
|
80
|
-
declare function Trans({ i18nKey, ...additionalProps }: TransProps): ReactNode[];
|
|
81
121
|
|
|
82
122
|
interface Ref<S> {
|
|
83
123
|
set value(action: SetStateAction<S>);
|
|
@@ -258,4 +298,4 @@ declare function useStore<S extends object, A extends Actions<S>, G extends Gett
|
|
|
258
298
|
|
|
259
299
|
type PropsWithDetailedHTML<T = HTMLDivElement> = DetailedHTMLProps<HTMLAttributes<T>, T>;
|
|
260
300
|
|
|
261
|
-
export { type Argument, type ArgumentArray, type AsyncStoreOptions, Case, type CaseProps, Default, type DefaultProps, Else, type ElseProps, type EventBusListener, type FetchRequestInterceptCallback, type FetchResponseInterceptCallback, If, type IfProps, type InjectComponent, Injector, type InjectorProps, type Mapping, type PersistantOptions, type PropsWithDetailedHTML, type ReadonlyArgumentArray, type Ref, Switch, type SwitchProps, Then, type ThenProps,
|
|
301
|
+
export { type Argument, type ArgumentArray, type AsyncStoreOptions, Case, type CaseProps, Default, type DefaultProps, Else, type ElseProps, type EventBusListener, type Exposer, type FetchRequestInterceptCallback, type FetchResponseInterceptCallback, If, type IfProps, type InjectComponent, Injector, type InjectorProps, type Mapping, type PersistantOptions, type PropsWithDetailedHTML, type ReadonlyArgumentArray, type Ref, Switch, type SwitchProps, Then, type ThenProps, Trigger, Unless, type UnlessProps, type UseAsyncStateOptions, type Value, type WatchCallback, type WatchOptions, type WrapperProps, type WrapperTag, cls, defineAsyncStore, defineStore, proxyWithPersistant, ref, track, useAsyncCallback, useAsyncState, useDebounce, useEventBus, useFetchRequestIntercept, useFetchResponseIntercept, useMounted, useStatus, useStore, useWatch, useWhenever, wrapper };
|