@pallasoft/ps-core-components 2.47.0 → 2.47.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/dist/esm/hooks/use-ps-optimistic-fetcher.js +2 -4
- package/dist/esm/hooks/use-ps-optimistic-save.js +1 -1
- package/dist/esm/hooks/use-ps-text-param.js +1 -1
- package/dist/esm/index.js +2 -12
- package/dist/esm/services/ps-draft-state-service.js +1 -1
- package/dist/hooks/use-ps-optimistic-fetcher.js +7 -9
- package/dist/hooks/use-ps-optimistic-save.js +4 -4
- package/dist/hooks/use-ps-text-param.js +2 -2
- package/dist/index.d.ts +2 -12
- package/dist/index.js +9 -12
- package/dist/interfaces/ps-optimistic-failure.d.ts +1 -1
- package/dist/interfaces/ps-optimistic-save-input.d.ts +1 -1
- package/dist/services/ps-draft-state-service.js +2 -2
- package/package.json +2 -2
- package/dist/constants/ps-optimistic-config.d.ts +0 -5
- package/dist/constants/ps-optimistic-config.js +0 -8
- package/dist/esm/constants/ps-optimistic-config.js +0 -5
- package/dist/esm/hooks/use-ps-change-queue.js +0 -36
- package/dist/esm/hooks/use-ps-debounced-value.js +0 -11
- package/dist/esm/hooks/use-ps-optimistic-rows.js +0 -29
- package/dist/esm/interfaces/ps-change-queue-input.js +0 -1
- package/dist/esm/interfaces/ps-change-queue-result.js +0 -1
- package/dist/esm/interfaces/ps-optimistic-changes.js +0 -1
- package/dist/esm/interfaces/ps-optimistic-failure-reason.js +0 -1
- package/dist/esm/interfaces/ps-optimistic-outcome.js +0 -1
- package/dist/esm/interfaces/ps-optimistic-rows-input.js +0 -1
- package/dist/esm/interfaces/ps-optimistic-rows-result.js +0 -1
- package/dist/esm/interfaces/ps-optimistic-save-spec.js +0 -1
- package/dist/esm/services/ps-deep-equal-service.js +0 -31
- package/dist/esm/services/ps-optimistic-fetcher-service.js +0 -12
- package/dist/esm/services/ps-optimistic-release-service.js +0 -38
- package/dist/esm/services/ps-optimistic-save-service.js +0 -64
- package/dist/hooks/use-ps-change-queue.d.ts +0 -3
- package/dist/hooks/use-ps-change-queue.js +0 -40
- package/dist/hooks/use-ps-debounced-value.d.ts +0 -1
- package/dist/hooks/use-ps-debounced-value.js +0 -15
- package/dist/hooks/use-ps-optimistic-rows.d.ts +0 -3
- package/dist/hooks/use-ps-optimistic-rows.js +0 -33
- package/dist/interfaces/ps-change-queue-input.d.ts +0 -5
- package/dist/interfaces/ps-change-queue-input.js +0 -2
- package/dist/interfaces/ps-change-queue-result.d.ts +0 -3
- package/dist/interfaces/ps-change-queue-result.js +0 -2
- package/dist/interfaces/ps-optimistic-changes.d.ts +0 -7
- package/dist/interfaces/ps-optimistic-changes.js +0 -2
- package/dist/interfaces/ps-optimistic-failure-reason.d.ts +0 -1
- package/dist/interfaces/ps-optimistic-failure-reason.js +0 -2
- package/dist/interfaces/ps-optimistic-outcome.d.ts +0 -5
- package/dist/interfaces/ps-optimistic-outcome.js +0 -2
- package/dist/interfaces/ps-optimistic-rows-input.d.ts +0 -6
- package/dist/interfaces/ps-optimistic-rows-input.js +0 -2
- package/dist/interfaces/ps-optimistic-rows-result.d.ts +0 -6
- package/dist/interfaces/ps-optimistic-rows-result.js +0 -2
- package/dist/interfaces/ps-optimistic-save-spec.d.ts +0 -11
- package/dist/interfaces/ps-optimistic-save-spec.js +0 -2
- package/dist/services/ps-deep-equal-service.d.ts +0 -5
- package/dist/services/ps-deep-equal-service.js +0 -35
- package/dist/services/ps-optimistic-fetcher-service.d.ts +0 -6
- package/dist/services/ps-optimistic-fetcher-service.js +0 -16
- package/dist/services/ps-optimistic-release-service.d.ts +0 -5
- package/dist/services/ps-optimistic-release-service.js +0 -42
- package/dist/services/ps-optimistic-save-service.d.ts +0 -11
- package/dist/services/ps-optimistic-save-service.js +0 -68
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
2
|
-
import { PsOptimisticConfig } from '
|
|
3
|
-
import {
|
|
4
|
-
import { usePsChangeQueue } from './use-ps-change-queue.js';
|
|
5
|
-
import { usePsOptimisticRows } from './use-ps-optimistic-rows.js';
|
|
2
|
+
import { PsOptimisticConfig, PsOptimisticFetcherService, } from '@pallasoft/ps-utilities';
|
|
3
|
+
import { usePsChangeQueue, usePsOptimisticRows } from '@pallasoft/ps-utilities/react';
|
|
6
4
|
export const usePsOptimisticFetcher = ({ apply, fetcher, isHolding = false, isSuccess, merge, onError, revalidator, rows, }) => {
|
|
7
5
|
const [isUnsettled, setIsUnsettled] = useState(false);
|
|
8
6
|
const submitted = useRef(0);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useCallback } from 'react';
|
|
2
|
-
import { PsOptimisticSaveService } from '
|
|
2
|
+
import { PsOptimisticSaveService } from '@pallasoft/ps-utilities';
|
|
3
3
|
import { usePsOptimisticFetcher } from './use-ps-optimistic-fetcher.js';
|
|
4
4
|
export const usePsOptimisticSave = ({ fetcher, isSuccess, onError, revalidator, rows, scopeId, spec, }) => {
|
|
5
5
|
const apply = useCallback((base, changes) => PsOptimisticSaveService.apply(base, changes, spec), [spec]);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useEffect, useState } from 'react';
|
|
2
|
+
import { usePsDebouncedValue } from '@pallasoft/ps-utilities/react';
|
|
2
3
|
import { PsQueryParamConfig } from '../constants/ps-query-param-config.js';
|
|
3
4
|
import { PsQueryParamService } from '../services/ps-query-param-service.js';
|
|
4
|
-
import { usePsDebouncedValue } from './use-ps-debounced-value.js';
|
|
5
5
|
export const usePsTextParam = ([searchParams, setSearchParams], { debounceMs, name, resetParams }) => {
|
|
6
6
|
const raw = searchParams.get(name);
|
|
7
7
|
const committed = raw === null ? '' : raw;
|
package/dist/esm/index.js
CHANGED
|
@@ -90,21 +90,13 @@ export * from './interfaces/ps-component-props.js';
|
|
|
90
90
|
export * from './models/ps-element-size.js';
|
|
91
91
|
export * from './models/ps-voice-orb.js';
|
|
92
92
|
export * from './models/ps-navigation-progress.js';
|
|
93
|
-
export * from './hooks/use-ps-debounced-value.js';
|
|
94
|
-
export * from './hooks/use-ps-change-queue.js';
|
|
95
|
-
export * from './interfaces/ps-change-queue-input.js';
|
|
96
|
-
export * from './interfaces/ps-change-queue-result.js';
|
|
97
93
|
export * from './hooks/use-ps-live.js';
|
|
98
94
|
export * from './hooks/use-ps-debounced-revalidate.js';
|
|
99
|
-
export * from './hooks/use-ps-optimistic-rows.js';
|
|
100
95
|
export * from './hooks/use-ps-optimistic-fetcher.js';
|
|
101
96
|
export * from './hooks/use-ps-optimistic-save.js';
|
|
102
|
-
export * from './constants/ps-optimistic-config.js';
|
|
103
97
|
export * from './interfaces/ps-optimistic-save-input.js';
|
|
104
98
|
export * from './interfaces/ps-optimistic-save-result.js';
|
|
105
|
-
export * from './interfaces/ps-optimistic-save-spec.js';
|
|
106
99
|
export * from './interfaces/ps-revalidation-args.js';
|
|
107
|
-
export * from './services/ps-optimistic-save-service.js';
|
|
108
100
|
export * from './services/ps-client-param-revalidation-service.js';
|
|
109
101
|
export * from './interfaces/ps-fetcher-like.js';
|
|
110
102
|
export * from './interfaces/ps-fetcher-submit-options.js';
|
|
@@ -114,10 +106,7 @@ export * from './interfaces/ps-live-open-options.js';
|
|
|
114
106
|
export * from './interfaces/ps-optimistic-fetcher-input.js';
|
|
115
107
|
export * from './interfaces/ps-optimistic-fetcher-result.js';
|
|
116
108
|
export * from './interfaces/ps-optimistic-failure.js';
|
|
117
|
-
export * from './interfaces/ps-optimistic-failure-reason.js';
|
|
118
109
|
export * from './interfaces/ps-revalidator-like.js';
|
|
119
|
-
export * from './interfaces/ps-optimistic-rows-input.js';
|
|
120
|
-
export * from './interfaces/ps-optimistic-rows-result.js';
|
|
121
110
|
export * from './hooks/use-ps-navigation-progress.js';
|
|
122
111
|
export * from './models/ps-draggable-grid.js';
|
|
123
112
|
export * from './constants/ps-draggable-grid.js';
|
|
@@ -132,7 +121,6 @@ export * from './constants/ps-data-boundary-variant.js';
|
|
|
132
121
|
export * from './hooks/use-ps-retained-promise.js';
|
|
133
122
|
export * from './hooks/use-ps-promise-value.js';
|
|
134
123
|
export * from './interfaces/ps-retained-promise-data.js';
|
|
135
|
-
export * from './services/ps-deep-equal-service.js';
|
|
136
124
|
export * from './components/ps-faq-answer.js';
|
|
137
125
|
export * from './components/ps-feature-grid.js';
|
|
138
126
|
export * from './components/ps-feature-card.js';
|
|
@@ -258,3 +246,5 @@ export * from './constants/ps-image-config.js';
|
|
|
258
246
|
export * from './models/ps-image-state-data.js';
|
|
259
247
|
export * from './services/ps-image-service.js';
|
|
260
248
|
export * from './components/ps-image.js';
|
|
249
|
+
export { PsDeepEqualService, PsOptimisticConfig, PsOptimisticSaveService, } from '@pallasoft/ps-utilities';
|
|
250
|
+
export { usePsChangeQueue, usePsDebouncedValue, usePsOptimisticRows, } from '@pallasoft/ps-utilities/react';
|
|
@@ -2,10 +2,8 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.usePsOptimisticFetcher = void 0;
|
|
4
4
|
const react_1 = require("react");
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const use_ps_change_queue_1 = require("./use-ps-change-queue");
|
|
8
|
-
const use_ps_optimistic_rows_1 = require("./use-ps-optimistic-rows");
|
|
5
|
+
const ps_utilities_1 = require("@pallasoft/ps-utilities");
|
|
6
|
+
const react_2 = require("@pallasoft/ps-utilities/react");
|
|
9
7
|
const usePsOptimisticFetcher = ({ apply, fetcher, isHolding = false, isSuccess, merge, onError, revalidator, rows, }) => {
|
|
10
8
|
const [isUnsettled, setIsUnsettled] = (0, react_1.useState)(false);
|
|
11
9
|
const submitted = (0, react_1.useRef)(0);
|
|
@@ -14,7 +12,7 @@ const usePsOptimisticFetcher = ({ apply, fetcher, isHolding = false, isSuccess,
|
|
|
14
12
|
const dataBefore = (0, react_1.useRef)(fetcher.data);
|
|
15
13
|
const dataSeen = (0, react_1.useRef)(fetcher.data);
|
|
16
14
|
const failure = (0, react_1.useRef)(null);
|
|
17
|
-
const { forgetLast, remember, rows: shown, } = (0,
|
|
15
|
+
const { forgetLast, remember, rows: shown, } = (0, react_2.usePsOptimisticRows)({
|
|
18
16
|
apply,
|
|
19
17
|
isHolding,
|
|
20
18
|
isSaving: isUnsettled || fetcher.state !== 'idle' || revalidator.state !== 'idle',
|
|
@@ -33,7 +31,7 @@ const usePsOptimisticFetcher = ({ apply, fetcher, isHolding = false, isSuccess,
|
|
|
33
31
|
const done = settle.current;
|
|
34
32
|
settle.current = null;
|
|
35
33
|
sawBusy.current = false;
|
|
36
|
-
done(
|
|
34
|
+
done(ps_utilities_1.PsOptimisticFetcherService.outcome(fetcher.data, dataBefore.current));
|
|
37
35
|
}, [fetcher.data, fetcher.state]);
|
|
38
36
|
(0, react_1.useEffect)(() => () => {
|
|
39
37
|
if (settle.current === null)
|
|
@@ -49,7 +47,7 @@ const usePsOptimisticFetcher = ({ apply, fetcher, isHolding = false, isSuccess,
|
|
|
49
47
|
settle.current = null;
|
|
50
48
|
resolve(outcome);
|
|
51
49
|
};
|
|
52
|
-
const timer = setTimeout(() => finish({ data: undefined, reason: 'timeout' }),
|
|
50
|
+
const timer = setTimeout(() => finish({ data: undefined, reason: 'timeout' }), ps_utilities_1.PsOptimisticConfig.submitTimeoutMs);
|
|
53
51
|
settle.current = finish;
|
|
54
52
|
sawBusy.current = false;
|
|
55
53
|
dataBefore.current = dataSeen.current;
|
|
@@ -64,7 +62,7 @@ const usePsOptimisticFetcher = ({ apply, fetcher, isHolding = false, isSuccess,
|
|
|
64
62
|
failure.current = null;
|
|
65
63
|
for (const submission of merge === undefined ? queued : merge(queued)) {
|
|
66
64
|
const outcome = await submitOne(submission);
|
|
67
|
-
const reason =
|
|
65
|
+
const reason = ps_utilities_1.PsOptimisticFetcherService.failureReason(outcome, isSuccess);
|
|
68
66
|
if (reason !== null) {
|
|
69
67
|
failure.current = { data: outcome.data, reason };
|
|
70
68
|
throw new Error(reason);
|
|
@@ -94,7 +92,7 @@ const usePsOptimisticFetcher = ({ apply, fetcher, isHolding = false, isSuccess,
|
|
|
94
92
|
}
|
|
95
93
|
onError({ ...cause, changes: [...failed, ...dropped] });
|
|
96
94
|
}, [forgetLast, onError]);
|
|
97
|
-
const queue = (0,
|
|
95
|
+
const queue = (0, react_2.usePsChangeQueue)({
|
|
98
96
|
onDrained: revalidate,
|
|
99
97
|
onFailed: forgetFailed,
|
|
100
98
|
send,
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.usePsOptimisticSave = void 0;
|
|
4
4
|
const react_1 = require("react");
|
|
5
|
-
const
|
|
5
|
+
const ps_utilities_1 = require("@pallasoft/ps-utilities");
|
|
6
6
|
const use_ps_optimistic_fetcher_1 = require("./use-ps-optimistic-fetcher");
|
|
7
7
|
const usePsOptimisticSave = ({ fetcher, isSuccess, onError, revalidator, rows, scopeId, spec, }) => {
|
|
8
|
-
const apply = (0, react_1.useCallback)((base, changes) =>
|
|
8
|
+
const apply = (0, react_1.useCallback)((base, changes) => ps_utilities_1.PsOptimisticSaveService.apply(base, changes, spec), [spec]);
|
|
9
9
|
const optimistic = (0, use_ps_optimistic_fetcher_1.usePsOptimisticFetcher)({
|
|
10
10
|
apply,
|
|
11
11
|
fetcher,
|
|
@@ -15,8 +15,8 @@ const usePsOptimisticSave = ({ fetcher, isSuccess, onError, revalidator, rows, s
|
|
|
15
15
|
rows,
|
|
16
16
|
});
|
|
17
17
|
const { submit } = optimistic;
|
|
18
|
-
const save = (0, react_1.useCallback)((values, existingId) => submit(
|
|
19
|
-
const remove = (0, react_1.useCallback)((ids) => submit(
|
|
18
|
+
const save = (0, react_1.useCallback)((values, existingId) => submit(ps_utilities_1.PsOptimisticSaveService.saveValues(spec, values, existingId, scopeId)), [scopeId, spec, submit]);
|
|
19
|
+
const remove = (0, react_1.useCallback)((ids) => submit(ps_utilities_1.PsOptimisticSaveService.removeValues(spec, ids)), [spec, submit]);
|
|
20
20
|
return { remove, rows: optimistic.rows, save };
|
|
21
21
|
};
|
|
22
22
|
exports.usePsOptimisticSave = usePsOptimisticSave;
|
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.usePsTextParam = void 0;
|
|
4
4
|
const react_1 = require("react");
|
|
5
|
+
const react_2 = require("@pallasoft/ps-utilities/react");
|
|
5
6
|
const ps_query_param_config_1 = require("../constants/ps-query-param-config");
|
|
6
7
|
const ps_query_param_service_1 = require("../services/ps-query-param-service");
|
|
7
|
-
const use_ps_debounced_value_1 = require("./use-ps-debounced-value");
|
|
8
8
|
const usePsTextParam = ([searchParams, setSearchParams], { debounceMs, name, resetParams }) => {
|
|
9
9
|
const raw = searchParams.get(name);
|
|
10
10
|
const committed = raw === null ? '' : raw;
|
|
11
11
|
const [value, setValue] = (0, react_1.useState)(committed);
|
|
12
|
-
const settled = (0,
|
|
12
|
+
const settled = (0, react_2.usePsDebouncedValue)(value, debounceMs);
|
|
13
13
|
(0, react_1.useEffect)(() => {
|
|
14
14
|
if (settled === committed)
|
|
15
15
|
return;
|
package/dist/index.d.ts
CHANGED
|
@@ -90,21 +90,13 @@ export * from './interfaces/ps-component-props';
|
|
|
90
90
|
export * from './models/ps-element-size';
|
|
91
91
|
export * from './models/ps-voice-orb';
|
|
92
92
|
export * from './models/ps-navigation-progress';
|
|
93
|
-
export * from './hooks/use-ps-debounced-value';
|
|
94
|
-
export * from './hooks/use-ps-change-queue';
|
|
95
|
-
export * from './interfaces/ps-change-queue-input';
|
|
96
|
-
export * from './interfaces/ps-change-queue-result';
|
|
97
93
|
export * from './hooks/use-ps-live';
|
|
98
94
|
export * from './hooks/use-ps-debounced-revalidate';
|
|
99
|
-
export * from './hooks/use-ps-optimistic-rows';
|
|
100
95
|
export * from './hooks/use-ps-optimistic-fetcher';
|
|
101
96
|
export * from './hooks/use-ps-optimistic-save';
|
|
102
|
-
export * from './constants/ps-optimistic-config';
|
|
103
97
|
export * from './interfaces/ps-optimistic-save-input';
|
|
104
98
|
export * from './interfaces/ps-optimistic-save-result';
|
|
105
|
-
export * from './interfaces/ps-optimistic-save-spec';
|
|
106
99
|
export * from './interfaces/ps-revalidation-args';
|
|
107
|
-
export * from './services/ps-optimistic-save-service';
|
|
108
100
|
export * from './services/ps-client-param-revalidation-service';
|
|
109
101
|
export * from './interfaces/ps-fetcher-like';
|
|
110
102
|
export * from './interfaces/ps-fetcher-submit-options';
|
|
@@ -114,10 +106,7 @@ export * from './interfaces/ps-live-open-options';
|
|
|
114
106
|
export * from './interfaces/ps-optimistic-fetcher-input';
|
|
115
107
|
export * from './interfaces/ps-optimistic-fetcher-result';
|
|
116
108
|
export * from './interfaces/ps-optimistic-failure';
|
|
117
|
-
export * from './interfaces/ps-optimistic-failure-reason';
|
|
118
109
|
export * from './interfaces/ps-revalidator-like';
|
|
119
|
-
export * from './interfaces/ps-optimistic-rows-input';
|
|
120
|
-
export * from './interfaces/ps-optimistic-rows-result';
|
|
121
110
|
export * from './hooks/use-ps-navigation-progress';
|
|
122
111
|
export * from './models/ps-draggable-grid';
|
|
123
112
|
export * from './constants/ps-draggable-grid';
|
|
@@ -132,7 +121,6 @@ export * from './constants/ps-data-boundary-variant';
|
|
|
132
121
|
export * from './hooks/use-ps-retained-promise';
|
|
133
122
|
export * from './hooks/use-ps-promise-value';
|
|
134
123
|
export * from './interfaces/ps-retained-promise-data';
|
|
135
|
-
export * from './services/ps-deep-equal-service';
|
|
136
124
|
export * from './components/ps-faq-answer';
|
|
137
125
|
export * from './components/ps-feature-grid';
|
|
138
126
|
export * from './components/ps-feature-card';
|
|
@@ -258,3 +246,5 @@ export * from './constants/ps-image-config';
|
|
|
258
246
|
export * from './models/ps-image-state-data';
|
|
259
247
|
export * from './services/ps-image-service';
|
|
260
248
|
export * from './components/ps-image';
|
|
249
|
+
export { PsDeepEqualService, PsOptimisticConfig, PsOptimisticSaveService, type PsOptimisticFailureReason, type PsOptimisticSaveSpec, } from '@pallasoft/ps-utilities';
|
|
250
|
+
export { usePsChangeQueue, usePsDebouncedValue, usePsOptimisticRows, type PsChangeQueueInput, type PsChangeQueueResult, type PsOptimisticRowsInput, type PsOptimisticRowsResult, } from '@pallasoft/ps-utilities/react';
|
package/dist/index.js
CHANGED
|
@@ -14,6 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.usePsOptimisticRows = exports.usePsDebouncedValue = exports.usePsChangeQueue = exports.PsOptimisticSaveService = exports.PsOptimisticConfig = exports.PsDeepEqualService = void 0;
|
|
17
18
|
__exportStar(require("./components/ps-layer"), exports);
|
|
18
19
|
__exportStar(require("./components/ps-accordion"), exports);
|
|
19
20
|
__exportStar(require("./components/ps-action-tile"), exports);
|
|
@@ -106,21 +107,13 @@ __exportStar(require("./interfaces/ps-component-props"), exports);
|
|
|
106
107
|
__exportStar(require("./models/ps-element-size"), exports);
|
|
107
108
|
__exportStar(require("./models/ps-voice-orb"), exports);
|
|
108
109
|
__exportStar(require("./models/ps-navigation-progress"), exports);
|
|
109
|
-
__exportStar(require("./hooks/use-ps-debounced-value"), exports);
|
|
110
|
-
__exportStar(require("./hooks/use-ps-change-queue"), exports);
|
|
111
|
-
__exportStar(require("./interfaces/ps-change-queue-input"), exports);
|
|
112
|
-
__exportStar(require("./interfaces/ps-change-queue-result"), exports);
|
|
113
110
|
__exportStar(require("./hooks/use-ps-live"), exports);
|
|
114
111
|
__exportStar(require("./hooks/use-ps-debounced-revalidate"), exports);
|
|
115
|
-
__exportStar(require("./hooks/use-ps-optimistic-rows"), exports);
|
|
116
112
|
__exportStar(require("./hooks/use-ps-optimistic-fetcher"), exports);
|
|
117
113
|
__exportStar(require("./hooks/use-ps-optimistic-save"), exports);
|
|
118
|
-
__exportStar(require("./constants/ps-optimistic-config"), exports);
|
|
119
114
|
__exportStar(require("./interfaces/ps-optimistic-save-input"), exports);
|
|
120
115
|
__exportStar(require("./interfaces/ps-optimistic-save-result"), exports);
|
|
121
|
-
__exportStar(require("./interfaces/ps-optimistic-save-spec"), exports);
|
|
122
116
|
__exportStar(require("./interfaces/ps-revalidation-args"), exports);
|
|
123
|
-
__exportStar(require("./services/ps-optimistic-save-service"), exports);
|
|
124
117
|
__exportStar(require("./services/ps-client-param-revalidation-service"), exports);
|
|
125
118
|
__exportStar(require("./interfaces/ps-fetcher-like"), exports);
|
|
126
119
|
__exportStar(require("./interfaces/ps-fetcher-submit-options"), exports);
|
|
@@ -130,10 +123,7 @@ __exportStar(require("./interfaces/ps-live-open-options"), exports);
|
|
|
130
123
|
__exportStar(require("./interfaces/ps-optimistic-fetcher-input"), exports);
|
|
131
124
|
__exportStar(require("./interfaces/ps-optimistic-fetcher-result"), exports);
|
|
132
125
|
__exportStar(require("./interfaces/ps-optimistic-failure"), exports);
|
|
133
|
-
__exportStar(require("./interfaces/ps-optimistic-failure-reason"), exports);
|
|
134
126
|
__exportStar(require("./interfaces/ps-revalidator-like"), exports);
|
|
135
|
-
__exportStar(require("./interfaces/ps-optimistic-rows-input"), exports);
|
|
136
|
-
__exportStar(require("./interfaces/ps-optimistic-rows-result"), exports);
|
|
137
127
|
__exportStar(require("./hooks/use-ps-navigation-progress"), exports);
|
|
138
128
|
__exportStar(require("./models/ps-draggable-grid"), exports);
|
|
139
129
|
__exportStar(require("./constants/ps-draggable-grid"), exports);
|
|
@@ -148,7 +138,6 @@ __exportStar(require("./constants/ps-data-boundary-variant"), exports);
|
|
|
148
138
|
__exportStar(require("./hooks/use-ps-retained-promise"), exports);
|
|
149
139
|
__exportStar(require("./hooks/use-ps-promise-value"), exports);
|
|
150
140
|
__exportStar(require("./interfaces/ps-retained-promise-data"), exports);
|
|
151
|
-
__exportStar(require("./services/ps-deep-equal-service"), exports);
|
|
152
141
|
__exportStar(require("./components/ps-faq-answer"), exports);
|
|
153
142
|
__exportStar(require("./components/ps-feature-grid"), exports);
|
|
154
143
|
__exportStar(require("./components/ps-feature-card"), exports);
|
|
@@ -274,3 +263,11 @@ __exportStar(require("./constants/ps-image-config"), exports);
|
|
|
274
263
|
__exportStar(require("./models/ps-image-state-data"), exports);
|
|
275
264
|
__exportStar(require("./services/ps-image-service"), exports);
|
|
276
265
|
__exportStar(require("./components/ps-image"), exports);
|
|
266
|
+
var ps_utilities_1 = require("@pallasoft/ps-utilities");
|
|
267
|
+
Object.defineProperty(exports, "PsDeepEqualService", { enumerable: true, get: function () { return ps_utilities_1.PsDeepEqualService; } });
|
|
268
|
+
Object.defineProperty(exports, "PsOptimisticConfig", { enumerable: true, get: function () { return ps_utilities_1.PsOptimisticConfig; } });
|
|
269
|
+
Object.defineProperty(exports, "PsOptimisticSaveService", { enumerable: true, get: function () { return ps_utilities_1.PsOptimisticSaveService; } });
|
|
270
|
+
var react_1 = require("@pallasoft/ps-utilities/react");
|
|
271
|
+
Object.defineProperty(exports, "usePsChangeQueue", { enumerable: true, get: function () { return react_1.usePsChangeQueue; } });
|
|
272
|
+
Object.defineProperty(exports, "usePsDebouncedValue", { enumerable: true, get: function () { return react_1.usePsDebouncedValue; } });
|
|
273
|
+
Object.defineProperty(exports, "usePsOptimisticRows", { enumerable: true, get: function () { return react_1.usePsOptimisticRows; } });
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import type { PsOptimisticSaveSpec } from '@pallasoft/ps-utilities';
|
|
1
2
|
import type { PsFetcherLike } from './ps-fetcher-like';
|
|
2
3
|
import type { PsOptimisticFailure } from './ps-optimistic-failure';
|
|
3
|
-
import type { PsOptimisticSaveSpec } from './ps-optimistic-save-spec';
|
|
4
4
|
import type { PsRevalidatorLike } from './ps-revalidator-like';
|
|
5
5
|
export interface PsOptimisticSaveInput<Row, Values, Data> {
|
|
6
6
|
fetcher: PsFetcherLike<Data>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.PsDraftStateService = void 0;
|
|
4
|
-
const
|
|
4
|
+
const ps_utilities_1 = require("@pallasoft/ps-utilities");
|
|
5
5
|
class PsDraftStateService {
|
|
6
6
|
static fresh(initial) {
|
|
7
7
|
return { baseline: initial, value: structuredClone(initial) };
|
|
@@ -9,7 +9,7 @@ class PsDraftStateService {
|
|
|
9
9
|
static isEqual(left, right, options) {
|
|
10
10
|
if (options !== undefined && options.isEqual !== undefined)
|
|
11
11
|
return options.isEqual(left, right);
|
|
12
|
-
return
|
|
12
|
+
return ps_utilities_1.PsDeepEqualService.isEqual(left, right);
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
15
|
exports.PsDraftStateService = PsDraftStateService;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pallasoft/ps-core-components",
|
|
3
|
-
"version": "2.47.
|
|
3
|
+
"version": "2.47.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/esm/index.js",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"@dnd-kit/utilities": "^3.2.2",
|
|
49
49
|
"@pallasoft/ps-icons": "^1.5.4",
|
|
50
50
|
"@pallasoft/ps-motion-components": "^1.2.2",
|
|
51
|
-
"@pallasoft/ps-utilities": "^2.
|
|
51
|
+
"@pallasoft/ps-utilities": "^2.29.0",
|
|
52
52
|
"@portabletext/react": "^3.2.4",
|
|
53
53
|
"@portabletext/types": "^2.0.13",
|
|
54
54
|
"@radix-ui/react-accordion": "^1.2.12",
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { useCallback, useEffect, useRef } from 'react';
|
|
2
|
-
export const usePsChangeQueue = ({ onDrained, onFailed, send, }) => {
|
|
3
|
-
const pending = useRef([]);
|
|
4
|
-
const isRunning = useRef(false);
|
|
5
|
-
const latest = useRef({ onDrained, onFailed, send });
|
|
6
|
-
useEffect(() => {
|
|
7
|
-
latest.current = { onDrained, onFailed, send };
|
|
8
|
-
}, [onDrained, onFailed, send]);
|
|
9
|
-
const run = useCallback(async () => {
|
|
10
|
-
if (isRunning.current)
|
|
11
|
-
return;
|
|
12
|
-
isRunning.current = true;
|
|
13
|
-
await Promise.resolve();
|
|
14
|
-
while (pending.current.length > 0) {
|
|
15
|
-
const batch = pending.current;
|
|
16
|
-
pending.current = [];
|
|
17
|
-
await new Promise((resolve) => resolve(latest.current.send(batch))).catch(() => {
|
|
18
|
-
const dropped = pending.current;
|
|
19
|
-
pending.current = [];
|
|
20
|
-
try {
|
|
21
|
-
latest.current.onFailed(batch, dropped);
|
|
22
|
-
}
|
|
23
|
-
catch {
|
|
24
|
-
return;
|
|
25
|
-
}
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
isRunning.current = false;
|
|
29
|
-
latest.current.onDrained();
|
|
30
|
-
}, []);
|
|
31
|
-
const enqueue = useCallback((change) => {
|
|
32
|
-
pending.current = [...pending.current, change];
|
|
33
|
-
void run();
|
|
34
|
-
}, [run]);
|
|
35
|
-
return { enqueue };
|
|
36
|
-
};
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { useEffect, useState } from 'react';
|
|
2
|
-
import { Client } from '@pallasoft/ps-utilities';
|
|
3
|
-
export const usePsDebouncedValue = (value, waitMs) => {
|
|
4
|
-
const [settled, setSettled] = useState(value);
|
|
5
|
-
useEffect(() => {
|
|
6
|
-
const debounced = Client.DebounceService.create((next) => setSettled(next), waitMs);
|
|
7
|
-
debounced.run(value);
|
|
8
|
-
return debounced.cancel;
|
|
9
|
-
}, [value, waitMs]);
|
|
10
|
-
return settled;
|
|
11
|
-
};
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { useCallback, useEffect, useMemo, useState } from 'react';
|
|
2
|
-
import { PsOptimisticConfig } from '../constants/ps-optimistic-config.js';
|
|
3
|
-
import { PsOptimisticReleaseService } from '../services/ps-optimistic-release-service.js';
|
|
4
|
-
export const usePsOptimisticRows = ({ apply, isHolding = false, isSaving, rows, }) => {
|
|
5
|
-
const [remembered, setRemembered] = useState(() => PsOptimisticReleaseService.empty(rows));
|
|
6
|
-
const isActive = isSaving || isHolding;
|
|
7
|
-
const current = PsOptimisticReleaseService.next(remembered, rows, isActive, isHolding, apply);
|
|
8
|
-
if (current !== remembered)
|
|
9
|
-
setRemembered(current);
|
|
10
|
-
const { changes } = current;
|
|
11
|
-
const isHeld = changes.length > 0 && !isActive;
|
|
12
|
-
const shown = useMemo(() => (changes.length === 0 ? rows : apply(rows, changes)), [apply, changes, rows]);
|
|
13
|
-
useEffect(() => {
|
|
14
|
-
if (!isHeld)
|
|
15
|
-
return undefined;
|
|
16
|
-
const timer = setTimeout(() => setRemembered(PsOptimisticReleaseService.empty(rows)), PsOptimisticConfig.releaseTimeoutMs);
|
|
17
|
-
return () => clearTimeout(timer);
|
|
18
|
-
}, [isHeld, changes, rows]);
|
|
19
|
-
const remember = useCallback((change) => setRemembered((previous) => ({
|
|
20
|
-
base: rows,
|
|
21
|
-
changes: [...previous.changes, change],
|
|
22
|
-
drainBase: null,
|
|
23
|
-
wasActive: previous.wasActive,
|
|
24
|
-
wasHolding: previous.wasHolding,
|
|
25
|
-
})), [rows]);
|
|
26
|
-
const forgetLast = useCallback(() => setRemembered((previous) => ({ ...previous, changes: previous.changes.slice(0, -1) })), []);
|
|
27
|
-
const rollback = useCallback(() => setRemembered(PsOptimisticReleaseService.empty(rows)), [rows]);
|
|
28
|
-
return { forgetLast, remember, rollback, rows: shown };
|
|
29
|
-
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
export class PsDeepEqualService {
|
|
2
|
-
static isEqual(left, right) {
|
|
3
|
-
if (Object.is(left, right))
|
|
4
|
-
return true;
|
|
5
|
-
if (typeof left !== 'object' || typeof right !== 'object')
|
|
6
|
-
return false;
|
|
7
|
-
if (left === null || right === null)
|
|
8
|
-
return false;
|
|
9
|
-
if (Array.isArray(left) || Array.isArray(right))
|
|
10
|
-
return PsDeepEqualService.isArrayEqual(left, right);
|
|
11
|
-
if (left instanceof Date || right instanceof Date) {
|
|
12
|
-
return left instanceof Date && right instanceof Date && left.getTime() === right.getTime();
|
|
13
|
-
}
|
|
14
|
-
return PsDeepEqualService.isRecordEqual(left, right);
|
|
15
|
-
}
|
|
16
|
-
static isArrayEqual(left, right) {
|
|
17
|
-
if (!Array.isArray(left) || !Array.isArray(right))
|
|
18
|
-
return false;
|
|
19
|
-
if (left.length !== right.length)
|
|
20
|
-
return false;
|
|
21
|
-
return left.every((item, index) => PsDeepEqualService.isEqual(item, right[index]));
|
|
22
|
-
}
|
|
23
|
-
static isRecordEqual(left, right) {
|
|
24
|
-
const leftEntries = Object.entries(left);
|
|
25
|
-
const rightRecord = { ...right };
|
|
26
|
-
if (leftEntries.length !== Object.keys(rightRecord).length)
|
|
27
|
-
return false;
|
|
28
|
-
return leftEntries.every(([key, value]) => Object.prototype.hasOwnProperty.call(rightRecord, key) &&
|
|
29
|
-
PsDeepEqualService.isEqual(value, rightRecord[key]));
|
|
30
|
-
}
|
|
31
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
export class PsOptimisticFetcherService {
|
|
2
|
-
static outcome(data, before) {
|
|
3
|
-
if (data === before)
|
|
4
|
-
return { data: undefined, reason: 'no-response' };
|
|
5
|
-
return { data, reason: 'settled' };
|
|
6
|
-
}
|
|
7
|
-
static failureReason(outcome, isSuccess) {
|
|
8
|
-
if (outcome.reason !== 'settled')
|
|
9
|
-
return outcome.reason;
|
|
10
|
-
return isSuccess(outcome.data) ? null : 'rejected';
|
|
11
|
-
}
|
|
12
|
-
}
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import { PsDeepEqualService } from './ps-deep-equal-service.js';
|
|
2
|
-
export class PsOptimisticReleaseService {
|
|
3
|
-
static empty(rows) {
|
|
4
|
-
return { base: rows, changes: [], drainBase: null, wasActive: false, wasHolding: false };
|
|
5
|
-
}
|
|
6
|
-
static next(remembered, rows, isActive, isHolding, apply) {
|
|
7
|
-
if (isActive) {
|
|
8
|
-
const wasHolding = remembered.wasHolding || isHolding;
|
|
9
|
-
if (remembered.wasActive &&
|
|
10
|
-
remembered.drainBase === null &&
|
|
11
|
-
remembered.wasHolding === wasHolding)
|
|
12
|
-
return remembered;
|
|
13
|
-
return { ...remembered, drainBase: null, wasActive: true, wasHolding };
|
|
14
|
-
}
|
|
15
|
-
if (remembered.changes.length === 0) {
|
|
16
|
-
if (remembered.base === rows && !remembered.wasActive)
|
|
17
|
-
return remembered;
|
|
18
|
-
return PsOptimisticReleaseService.empty(rows);
|
|
19
|
-
}
|
|
20
|
-
if (remembered.wasActive) {
|
|
21
|
-
if (remembered.wasHolding && rows !== remembered.base) {
|
|
22
|
-
return PsOptimisticReleaseService.empty(rows);
|
|
23
|
-
}
|
|
24
|
-
if (!PsDeepEqualService.isEqual(rows, remembered.base)) {
|
|
25
|
-
return PsOptimisticReleaseService.empty(rows);
|
|
26
|
-
}
|
|
27
|
-
return { ...remembered, drainBase: rows, wasActive: false, wasHolding: false };
|
|
28
|
-
}
|
|
29
|
-
const reference = remembered.drainBase === null ? remembered.base : remembered.drainBase;
|
|
30
|
-
if (!PsDeepEqualService.isEqual(rows, reference)) {
|
|
31
|
-
return PsOptimisticReleaseService.empty(rows);
|
|
32
|
-
}
|
|
33
|
-
if (PsDeepEqualService.isEqual(apply(rows, remembered.changes), rows)) {
|
|
34
|
-
return PsOptimisticReleaseService.empty(rows);
|
|
35
|
-
}
|
|
36
|
-
return remembered;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import { PsOptimisticConfig } from '../constants/ps-optimistic-config.js';
|
|
2
|
-
export class PsOptimisticSaveService {
|
|
3
|
-
static isPending(id) {
|
|
4
|
-
return id.startsWith(PsOptimisticConfig.pendingPrefix);
|
|
5
|
-
}
|
|
6
|
-
static pendingId() {
|
|
7
|
-
return `${PsOptimisticConfig.pendingPrefix}${crypto.randomUUID()}`;
|
|
8
|
-
}
|
|
9
|
-
static saveValues(spec, values, existingId, scopeId) {
|
|
10
|
-
const fields = spec.isFlat
|
|
11
|
-
? Object.fromEntries(Object.entries(values).map(([key, value]) => [key, String(value)]))
|
|
12
|
-
: { values: JSON.stringify(values) };
|
|
13
|
-
return {
|
|
14
|
-
...fields,
|
|
15
|
-
[spec.idField]: existingId,
|
|
16
|
-
intent: spec.intent,
|
|
17
|
-
pendingId: PsOptimisticSaveService.pendingId(),
|
|
18
|
-
scopeId,
|
|
19
|
-
};
|
|
20
|
-
}
|
|
21
|
-
static removeValues(spec, ids) {
|
|
22
|
-
return spec.remove === undefined
|
|
23
|
-
? {}
|
|
24
|
-
: { [spec.remove.idsField]: JSON.stringify(ids), intent: spec.remove.intent };
|
|
25
|
-
}
|
|
26
|
-
static apply(rows, changes, spec) {
|
|
27
|
-
return changes.reduce((current, change) => {
|
|
28
|
-
if (change.intent === spec.intent)
|
|
29
|
-
return PsOptimisticSaveService.saved(current, change, spec);
|
|
30
|
-
if (spec.remove !== undefined && change.intent === spec.remove.intent)
|
|
31
|
-
return PsOptimisticSaveService.removed(current, change, spec, spec.remove.idsField);
|
|
32
|
-
return current;
|
|
33
|
-
}, rows);
|
|
34
|
-
}
|
|
35
|
-
static read(raw) {
|
|
36
|
-
if (raw === undefined)
|
|
37
|
-
return null;
|
|
38
|
-
try {
|
|
39
|
-
return JSON.parse(raw);
|
|
40
|
-
}
|
|
41
|
-
catch {
|
|
42
|
-
return null;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
static saved(rows, change, spec) {
|
|
46
|
-
const parsed = spec.isFlat ? change : PsOptimisticSaveService.read(change.values);
|
|
47
|
-
if (parsed === null || typeof parsed !== 'object')
|
|
48
|
-
return rows;
|
|
49
|
-
const existingId = change[spec.idField];
|
|
50
|
-
const id = existingId === '' ? change.pendingId : existingId;
|
|
51
|
-
const previous = rows.find((row) => spec.getId(row) === existingId);
|
|
52
|
-
const built = spec.build(parsed, id, previous === undefined ? null : previous, change.scopeId);
|
|
53
|
-
if (built === null)
|
|
54
|
-
return rows;
|
|
55
|
-
return previous === undefined
|
|
56
|
-
? [...rows, built]
|
|
57
|
-
: rows.map((row) => (spec.getId(row) === existingId ? built : row));
|
|
58
|
-
}
|
|
59
|
-
static removed(rows, change, spec, idsField) {
|
|
60
|
-
const parsed = PsOptimisticSaveService.read(change[idsField]);
|
|
61
|
-
const ids = new Set(Array.isArray(parsed) ? parsed : []);
|
|
62
|
-
return rows.filter((row) => !ids.has(spec.getId(row)));
|
|
63
|
-
}
|
|
64
|
-
}
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import type { PsChangeQueueInput } from '../interfaces/ps-change-queue-input';
|
|
2
|
-
import type { PsChangeQueueResult } from '../interfaces/ps-change-queue-result';
|
|
3
|
-
export declare const usePsChangeQueue: <Change>({ onDrained, onFailed, send, }: PsChangeQueueInput<Change>) => PsChangeQueueResult<Change>;
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.usePsChangeQueue = void 0;
|
|
4
|
-
const react_1 = require("react");
|
|
5
|
-
const usePsChangeQueue = ({ onDrained, onFailed, send, }) => {
|
|
6
|
-
const pending = (0, react_1.useRef)([]);
|
|
7
|
-
const isRunning = (0, react_1.useRef)(false);
|
|
8
|
-
const latest = (0, react_1.useRef)({ onDrained, onFailed, send });
|
|
9
|
-
(0, react_1.useEffect)(() => {
|
|
10
|
-
latest.current = { onDrained, onFailed, send };
|
|
11
|
-
}, [onDrained, onFailed, send]);
|
|
12
|
-
const run = (0, react_1.useCallback)(async () => {
|
|
13
|
-
if (isRunning.current)
|
|
14
|
-
return;
|
|
15
|
-
isRunning.current = true;
|
|
16
|
-
await Promise.resolve();
|
|
17
|
-
while (pending.current.length > 0) {
|
|
18
|
-
const batch = pending.current;
|
|
19
|
-
pending.current = [];
|
|
20
|
-
await new Promise((resolve) => resolve(latest.current.send(batch))).catch(() => {
|
|
21
|
-
const dropped = pending.current;
|
|
22
|
-
pending.current = [];
|
|
23
|
-
try {
|
|
24
|
-
latest.current.onFailed(batch, dropped);
|
|
25
|
-
}
|
|
26
|
-
catch {
|
|
27
|
-
return;
|
|
28
|
-
}
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
isRunning.current = false;
|
|
32
|
-
latest.current.onDrained();
|
|
33
|
-
}, []);
|
|
34
|
-
const enqueue = (0, react_1.useCallback)((change) => {
|
|
35
|
-
pending.current = [...pending.current, change];
|
|
36
|
-
void run();
|
|
37
|
-
}, [run]);
|
|
38
|
-
return { enqueue };
|
|
39
|
-
};
|
|
40
|
-
exports.usePsChangeQueue = usePsChangeQueue;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const usePsDebouncedValue: <T>(value: T, waitMs: number) => T;
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.usePsDebouncedValue = void 0;
|
|
4
|
-
const react_1 = require("react");
|
|
5
|
-
const ps_utilities_1 = require("@pallasoft/ps-utilities");
|
|
6
|
-
const usePsDebouncedValue = (value, waitMs) => {
|
|
7
|
-
const [settled, setSettled] = (0, react_1.useState)(value);
|
|
8
|
-
(0, react_1.useEffect)(() => {
|
|
9
|
-
const debounced = ps_utilities_1.Client.DebounceService.create((next) => setSettled(next), waitMs);
|
|
10
|
-
debounced.run(value);
|
|
11
|
-
return debounced.cancel;
|
|
12
|
-
}, [value, waitMs]);
|
|
13
|
-
return settled;
|
|
14
|
-
};
|
|
15
|
-
exports.usePsDebouncedValue = usePsDebouncedValue;
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import type { PsOptimisticRowsInput } from '../interfaces/ps-optimistic-rows-input';
|
|
2
|
-
import type { PsOptimisticRowsResult } from '../interfaces/ps-optimistic-rows-result';
|
|
3
|
-
export declare const usePsOptimisticRows: <Row, Change>({ apply, isHolding, isSaving, rows, }: PsOptimisticRowsInput<Row, Change>) => PsOptimisticRowsResult<Row, Change>;
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.usePsOptimisticRows = void 0;
|
|
4
|
-
const react_1 = require("react");
|
|
5
|
-
const ps_optimistic_config_1 = require("../constants/ps-optimistic-config");
|
|
6
|
-
const ps_optimistic_release_service_1 = require("../services/ps-optimistic-release-service");
|
|
7
|
-
const usePsOptimisticRows = ({ apply, isHolding = false, isSaving, rows, }) => {
|
|
8
|
-
const [remembered, setRemembered] = (0, react_1.useState)(() => ps_optimistic_release_service_1.PsOptimisticReleaseService.empty(rows));
|
|
9
|
-
const isActive = isSaving || isHolding;
|
|
10
|
-
const current = ps_optimistic_release_service_1.PsOptimisticReleaseService.next(remembered, rows, isActive, isHolding, apply);
|
|
11
|
-
if (current !== remembered)
|
|
12
|
-
setRemembered(current);
|
|
13
|
-
const { changes } = current;
|
|
14
|
-
const isHeld = changes.length > 0 && !isActive;
|
|
15
|
-
const shown = (0, react_1.useMemo)(() => (changes.length === 0 ? rows : apply(rows, changes)), [apply, changes, rows]);
|
|
16
|
-
(0, react_1.useEffect)(() => {
|
|
17
|
-
if (!isHeld)
|
|
18
|
-
return undefined;
|
|
19
|
-
const timer = setTimeout(() => setRemembered(ps_optimistic_release_service_1.PsOptimisticReleaseService.empty(rows)), ps_optimistic_config_1.PsOptimisticConfig.releaseTimeoutMs);
|
|
20
|
-
return () => clearTimeout(timer);
|
|
21
|
-
}, [isHeld, changes, rows]);
|
|
22
|
-
const remember = (0, react_1.useCallback)((change) => setRemembered((previous) => ({
|
|
23
|
-
base: rows,
|
|
24
|
-
changes: [...previous.changes, change],
|
|
25
|
-
drainBase: null,
|
|
26
|
-
wasActive: previous.wasActive,
|
|
27
|
-
wasHolding: previous.wasHolding,
|
|
28
|
-
})), [rows]);
|
|
29
|
-
const forgetLast = (0, react_1.useCallback)(() => setRemembered((previous) => ({ ...previous, changes: previous.changes.slice(0, -1) })), []);
|
|
30
|
-
const rollback = (0, react_1.useCallback)(() => setRemembered(ps_optimistic_release_service_1.PsOptimisticReleaseService.empty(rows)), [rows]);
|
|
31
|
-
return { forgetLast, remember, rollback, rows: shown };
|
|
32
|
-
};
|
|
33
|
-
exports.usePsOptimisticRows = usePsOptimisticRows;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export type PsOptimisticFailureReason = 'error' | 'no-response' | 'rejected' | 'timeout' | 'unmounted';
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
export interface PsOptimisticSaveSpec<Row, Values> {
|
|
2
|
-
build: (values: Values, id: string, previous: Row | null, scopeId: string) => Row | null;
|
|
3
|
-
getId: (row: Row) => string;
|
|
4
|
-
idField: string;
|
|
5
|
-
intent: string;
|
|
6
|
-
isFlat: boolean;
|
|
7
|
-
remove?: {
|
|
8
|
-
idsField: string;
|
|
9
|
-
intent: string;
|
|
10
|
-
};
|
|
11
|
-
}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.PsDeepEqualService = void 0;
|
|
4
|
-
class PsDeepEqualService {
|
|
5
|
-
static isEqual(left, right) {
|
|
6
|
-
if (Object.is(left, right))
|
|
7
|
-
return true;
|
|
8
|
-
if (typeof left !== 'object' || typeof right !== 'object')
|
|
9
|
-
return false;
|
|
10
|
-
if (left === null || right === null)
|
|
11
|
-
return false;
|
|
12
|
-
if (Array.isArray(left) || Array.isArray(right))
|
|
13
|
-
return PsDeepEqualService.isArrayEqual(left, right);
|
|
14
|
-
if (left instanceof Date || right instanceof Date) {
|
|
15
|
-
return left instanceof Date && right instanceof Date && left.getTime() === right.getTime();
|
|
16
|
-
}
|
|
17
|
-
return PsDeepEqualService.isRecordEqual(left, right);
|
|
18
|
-
}
|
|
19
|
-
static isArrayEqual(left, right) {
|
|
20
|
-
if (!Array.isArray(left) || !Array.isArray(right))
|
|
21
|
-
return false;
|
|
22
|
-
if (left.length !== right.length)
|
|
23
|
-
return false;
|
|
24
|
-
return left.every((item, index) => PsDeepEqualService.isEqual(item, right[index]));
|
|
25
|
-
}
|
|
26
|
-
static isRecordEqual(left, right) {
|
|
27
|
-
const leftEntries = Object.entries(left);
|
|
28
|
-
const rightRecord = { ...right };
|
|
29
|
-
if (leftEntries.length !== Object.keys(rightRecord).length)
|
|
30
|
-
return false;
|
|
31
|
-
return leftEntries.every(([key, value]) => Object.prototype.hasOwnProperty.call(rightRecord, key) &&
|
|
32
|
-
PsDeepEqualService.isEqual(value, rightRecord[key]));
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
exports.PsDeepEqualService = PsDeepEqualService;
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import type { PsOptimisticFailureReason } from '../interfaces/ps-optimistic-failure-reason';
|
|
2
|
-
import type { PsOptimisticOutcome } from '../interfaces/ps-optimistic-outcome';
|
|
3
|
-
export declare class PsOptimisticFetcherService {
|
|
4
|
-
static outcome<Data>(data: Data | undefined, before: Data | undefined): PsOptimisticOutcome<Data>;
|
|
5
|
-
static failureReason<Data>(outcome: PsOptimisticOutcome<Data>, isSuccess: (data: Data | undefined) => boolean): PsOptimisticFailureReason | null;
|
|
6
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.PsOptimisticFetcherService = void 0;
|
|
4
|
-
class PsOptimisticFetcherService {
|
|
5
|
-
static outcome(data, before) {
|
|
6
|
-
if (data === before)
|
|
7
|
-
return { data: undefined, reason: 'no-response' };
|
|
8
|
-
return { data, reason: 'settled' };
|
|
9
|
-
}
|
|
10
|
-
static failureReason(outcome, isSuccess) {
|
|
11
|
-
if (outcome.reason !== 'settled')
|
|
12
|
-
return outcome.reason;
|
|
13
|
-
return isSuccess(outcome.data) ? null : 'rejected';
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
exports.PsOptimisticFetcherService = PsOptimisticFetcherService;
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import type { PsOptimisticChanges } from '../interfaces/ps-optimistic-changes';
|
|
2
|
-
export declare class PsOptimisticReleaseService {
|
|
3
|
-
static empty<Row, Change>(rows: Row[]): PsOptimisticChanges<Row, Change>;
|
|
4
|
-
static next<Row, Change>(remembered: PsOptimisticChanges<Row, Change>, rows: Row[], isActive: boolean, isHolding: boolean, apply: (rows: Row[], changes: Change[]) => Row[]): PsOptimisticChanges<Row, Change>;
|
|
5
|
-
}
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.PsOptimisticReleaseService = void 0;
|
|
4
|
-
const ps_deep_equal_service_1 = require("./ps-deep-equal-service");
|
|
5
|
-
class PsOptimisticReleaseService {
|
|
6
|
-
static empty(rows) {
|
|
7
|
-
return { base: rows, changes: [], drainBase: null, wasActive: false, wasHolding: false };
|
|
8
|
-
}
|
|
9
|
-
static next(remembered, rows, isActive, isHolding, apply) {
|
|
10
|
-
if (isActive) {
|
|
11
|
-
const wasHolding = remembered.wasHolding || isHolding;
|
|
12
|
-
if (remembered.wasActive &&
|
|
13
|
-
remembered.drainBase === null &&
|
|
14
|
-
remembered.wasHolding === wasHolding)
|
|
15
|
-
return remembered;
|
|
16
|
-
return { ...remembered, drainBase: null, wasActive: true, wasHolding };
|
|
17
|
-
}
|
|
18
|
-
if (remembered.changes.length === 0) {
|
|
19
|
-
if (remembered.base === rows && !remembered.wasActive)
|
|
20
|
-
return remembered;
|
|
21
|
-
return PsOptimisticReleaseService.empty(rows);
|
|
22
|
-
}
|
|
23
|
-
if (remembered.wasActive) {
|
|
24
|
-
if (remembered.wasHolding && rows !== remembered.base) {
|
|
25
|
-
return PsOptimisticReleaseService.empty(rows);
|
|
26
|
-
}
|
|
27
|
-
if (!ps_deep_equal_service_1.PsDeepEqualService.isEqual(rows, remembered.base)) {
|
|
28
|
-
return PsOptimisticReleaseService.empty(rows);
|
|
29
|
-
}
|
|
30
|
-
return { ...remembered, drainBase: rows, wasActive: false, wasHolding: false };
|
|
31
|
-
}
|
|
32
|
-
const reference = remembered.drainBase === null ? remembered.base : remembered.drainBase;
|
|
33
|
-
if (!ps_deep_equal_service_1.PsDeepEqualService.isEqual(rows, reference)) {
|
|
34
|
-
return PsOptimisticReleaseService.empty(rows);
|
|
35
|
-
}
|
|
36
|
-
if (ps_deep_equal_service_1.PsDeepEqualService.isEqual(apply(rows, remembered.changes), rows)) {
|
|
37
|
-
return PsOptimisticReleaseService.empty(rows);
|
|
38
|
-
}
|
|
39
|
-
return remembered;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
exports.PsOptimisticReleaseService = PsOptimisticReleaseService;
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import type { PsOptimisticSaveSpec } from '../interfaces/ps-optimistic-save-spec';
|
|
2
|
-
export declare class PsOptimisticSaveService {
|
|
3
|
-
static isPending(id: string): boolean;
|
|
4
|
-
static pendingId(): string;
|
|
5
|
-
static saveValues<Row, Values>(spec: PsOptimisticSaveSpec<Row, Values>, values: Values, existingId: string, scopeId: string): Record<string, string>;
|
|
6
|
-
static removeValues<Row, Values>(spec: PsOptimisticSaveSpec<Row, Values>, ids: string[]): Record<string, string>;
|
|
7
|
-
static apply<Row, Values>(rows: Row[], changes: Record<string, string>[], spec: PsOptimisticSaveSpec<Row, Values>): Row[];
|
|
8
|
-
private static read;
|
|
9
|
-
private static saved;
|
|
10
|
-
private static removed;
|
|
11
|
-
}
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.PsOptimisticSaveService = void 0;
|
|
4
|
-
const ps_optimistic_config_1 = require("../constants/ps-optimistic-config");
|
|
5
|
-
class PsOptimisticSaveService {
|
|
6
|
-
static isPending(id) {
|
|
7
|
-
return id.startsWith(ps_optimistic_config_1.PsOptimisticConfig.pendingPrefix);
|
|
8
|
-
}
|
|
9
|
-
static pendingId() {
|
|
10
|
-
return `${ps_optimistic_config_1.PsOptimisticConfig.pendingPrefix}${crypto.randomUUID()}`;
|
|
11
|
-
}
|
|
12
|
-
static saveValues(spec, values, existingId, scopeId) {
|
|
13
|
-
const fields = spec.isFlat
|
|
14
|
-
? Object.fromEntries(Object.entries(values).map(([key, value]) => [key, String(value)]))
|
|
15
|
-
: { values: JSON.stringify(values) };
|
|
16
|
-
return {
|
|
17
|
-
...fields,
|
|
18
|
-
[spec.idField]: existingId,
|
|
19
|
-
intent: spec.intent,
|
|
20
|
-
pendingId: PsOptimisticSaveService.pendingId(),
|
|
21
|
-
scopeId,
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
static removeValues(spec, ids) {
|
|
25
|
-
return spec.remove === undefined
|
|
26
|
-
? {}
|
|
27
|
-
: { [spec.remove.idsField]: JSON.stringify(ids), intent: spec.remove.intent };
|
|
28
|
-
}
|
|
29
|
-
static apply(rows, changes, spec) {
|
|
30
|
-
return changes.reduce((current, change) => {
|
|
31
|
-
if (change.intent === spec.intent)
|
|
32
|
-
return PsOptimisticSaveService.saved(current, change, spec);
|
|
33
|
-
if (spec.remove !== undefined && change.intent === spec.remove.intent)
|
|
34
|
-
return PsOptimisticSaveService.removed(current, change, spec, spec.remove.idsField);
|
|
35
|
-
return current;
|
|
36
|
-
}, rows);
|
|
37
|
-
}
|
|
38
|
-
static read(raw) {
|
|
39
|
-
if (raw === undefined)
|
|
40
|
-
return null;
|
|
41
|
-
try {
|
|
42
|
-
return JSON.parse(raw);
|
|
43
|
-
}
|
|
44
|
-
catch {
|
|
45
|
-
return null;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
static saved(rows, change, spec) {
|
|
49
|
-
const parsed = spec.isFlat ? change : PsOptimisticSaveService.read(change.values);
|
|
50
|
-
if (parsed === null || typeof parsed !== 'object')
|
|
51
|
-
return rows;
|
|
52
|
-
const existingId = change[spec.idField];
|
|
53
|
-
const id = existingId === '' ? change.pendingId : existingId;
|
|
54
|
-
const previous = rows.find((row) => spec.getId(row) === existingId);
|
|
55
|
-
const built = spec.build(parsed, id, previous === undefined ? null : previous, change.scopeId);
|
|
56
|
-
if (built === null)
|
|
57
|
-
return rows;
|
|
58
|
-
return previous === undefined
|
|
59
|
-
? [...rows, built]
|
|
60
|
-
: rows.map((row) => (spec.getId(row) === existingId ? built : row));
|
|
61
|
-
}
|
|
62
|
-
static removed(rows, change, spec, idsField) {
|
|
63
|
-
const parsed = PsOptimisticSaveService.read(change[idsField]);
|
|
64
|
-
const ids = new Set(Array.isArray(parsed) ? parsed : []);
|
|
65
|
-
return rows.filter((row) => !ids.has(spec.getId(row)));
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
exports.PsOptimisticSaveService = PsOptimisticSaveService;
|