@blueprint-ts/core 4.1.0-beta.6 → 5.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/dist/bulkRequests/BulkRequestSender.js +81 -102
- package/dist/bulkRequests/BulkRequestWrapper.js +16 -26
- package/dist/laravel/pagination/dataDrivers/RequestDriver.js +1 -0
- package/dist/pagination/BasePaginator.js +4 -4
- package/dist/pagination/PageAwarePaginator.js +4 -1
- package/dist/pagination/StatePaginator.js +6 -3
- package/dist/pagination/dataDrivers/ArrayDriver.js +1 -0
- package/dist/pagination/dtos/PaginationDataDto.js +2 -0
- package/dist/pagination/dtos/StatePaginationDataDto.js +1 -0
- package/dist/pagination/frontendDrivers/VueBaseViewDriver.js +2 -0
- package/dist/pagination/frontendDrivers/VuePaginationDriver.js +6 -0
- package/dist/persistenceDrivers/LocalStorageDriver.js +1 -0
- package/dist/persistenceDrivers/MemoryPersistenceDriver.js +2 -1
- package/dist/persistenceDrivers/SessionStorageDriver.js +1 -0
- package/dist/requests/BaseRequest.js +93 -100
- package/dist/requests/ErrorHandler.js +21 -31
- package/dist/requests/RequestErrorRouter.js +12 -25
- package/dist/requests/bodies/BinaryBody.js +2 -0
- package/dist/requests/bodies/FormDataBody.js +1 -0
- package/dist/requests/bodies/JsonBody.js +1 -0
- package/dist/requests/drivers/fetch/FetchDriver.js +26 -26
- package/dist/requests/drivers/fetch/FetchResponse.js +7 -21
- package/dist/requests/drivers/mock/MockRequestDriver.js +190 -169
- package/dist/requests/drivers/mock/MockRequestTestHelpers.js +10 -4
- package/dist/requests/drivers/mock/MockResponseHandler.js +12 -23
- package/dist/requests/drivers/xhr/XMLHttpRequestDriver.js +68 -74
- package/dist/requests/drivers/xhr/XMLHttpRequestResponse.js +9 -21
- package/dist/requests/exceptions/InvalidJsonException.js +1 -0
- package/dist/requests/exceptions/ResponseBodyException.js +1 -0
- package/dist/requests/exceptions/ResponseException.js +1 -0
- package/dist/requests/exceptions/StaleResponseException.js +1 -0
- package/dist/requests/factories/BinaryBodyFactory.js +1 -0
- package/dist/requests/responses/BaseResponse.js +9 -21
- package/dist/requests/responses/BlobResponse.js +1 -0
- package/dist/support/DeferredPromise.js +5 -4
- package/dist/vue/composables/useConfirmDialog.js +7 -18
- package/dist/vue/composables/useGlobalCheckbox.js +55 -66
- package/dist/vue/forms/BaseForm.d.ts +11 -8
- package/dist/vue/forms/BaseForm.js +153 -149
- package/dist/vue/forms/PropertyAwareArray.js +0 -1
- package/dist/vue/forms/PropertyAwareObject.js +4 -2
- package/dist/vue/forms/index.d.ts +2 -2
- package/dist/vue/forms/persistence/types.d.ts +2 -0
- package/dist/vue/forms/validation/rules/BaseRule.js +3 -16
- package/dist/vue/forms/validation/rules/ConfirmedRule.js +2 -0
- package/dist/vue/forms/validation/rules/EmailRule.js +1 -0
- package/dist/vue/forms/validation/rules/JsonRule.js +2 -1
- package/dist/vue/forms/validation/rules/MinRule.js +2 -0
- package/dist/vue/forms/validation/rules/PrecognitiveRule.js +21 -31
- package/dist/vue/forms/validation/rules/RequiredRule.js +1 -0
- package/dist/vue/forms/validation/rules/UrlRule.js +2 -1
- package/dist/vue/requests/loaders/VueRequestBatchLoader.js +3 -3
- package/dist/vue/requests/loaders/VueRequestLoader.js +1 -0
- package/dist/vue/router/routeResourceBinding/RouteResourceBoundView.js +8 -18
- package/dist/vue/router/routeResourceBinding/RouteResourceRequestResolver.js +4 -14
- package/dist/vue/router/routeResourceBinding/defineRoute.js +8 -7
- package/dist/vue/router/routeResourceBinding/installRouteInjection.js +12 -21
- package/dist/vue/router/routeResourceBinding/useRouteResource.js +5 -17
- package/dist/vue/state/State.d.ts +2 -0
- package/dist/vue/state/State.js +24 -11
- package/dist/vue/state/index.d.ts +2 -1
- package/package.json +27 -27
|
@@ -1,21 +1,8 @@
|
|
|
1
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
1
|
export class BaseRule {
|
|
11
|
-
|
|
12
|
-
this.dependsOn = [];
|
|
13
|
-
}
|
|
2
|
+
dependsOn = [];
|
|
14
3
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
15
|
-
validateAsync(_value, _state, _context) {
|
|
16
|
-
return
|
|
17
|
-
return null;
|
|
18
|
-
});
|
|
4
|
+
async validateAsync(_value, _state, _context) {
|
|
5
|
+
return null;
|
|
19
6
|
}
|
|
20
7
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
21
8
|
getAsyncValidationPaths(field, _state) {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { BaseRule } from './BaseRule';
|
|
2
2
|
export class JsonRule extends BaseRule {
|
|
3
|
+
message;
|
|
3
4
|
constructor(message = 'Please enter valid JSON') {
|
|
4
5
|
super();
|
|
5
6
|
this.message = message;
|
|
@@ -15,7 +16,7 @@ export class JsonRule extends BaseRule {
|
|
|
15
16
|
JSON.parse(value);
|
|
16
17
|
return true;
|
|
17
18
|
}
|
|
18
|
-
catch
|
|
19
|
+
catch {
|
|
19
20
|
return false;
|
|
20
21
|
}
|
|
21
22
|
}
|
|
@@ -1,15 +1,8 @@
|
|
|
1
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
1
|
import { ValidationException } from '../../../../requests/exceptions/ValidationException';
|
|
11
2
|
import { BaseRule } from './BaseRule';
|
|
12
3
|
export class PrecognitiveRule extends BaseRule {
|
|
4
|
+
requestFactory;
|
|
5
|
+
options;
|
|
13
6
|
constructor(requestFactory, options = {}) {
|
|
14
7
|
super();
|
|
15
8
|
this.requestFactory = requestFactory;
|
|
@@ -31,28 +24,25 @@ export class PrecognitiveRule extends BaseRule {
|
|
|
31
24
|
}
|
|
32
25
|
return [String(field)];
|
|
33
26
|
}
|
|
34
|
-
validateAsync(_value, state, context) {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
Precognition: 'true',
|
|
43
|
-
'Precognition-Validate-Only': validateOnly.join(',')
|
|
44
|
-
});
|
|
45
|
-
try {
|
|
46
|
-
yield request.send({ resolveBody: false });
|
|
47
|
-
return {};
|
|
48
|
-
}
|
|
49
|
-
catch (error) {
|
|
50
|
-
if (error instanceof ValidationException) {
|
|
51
|
-
const body = error.getBody();
|
|
52
|
-
return (_e = (_d = (_c = (_b = this.options).resolveErrors) === null || _c === void 0 ? void 0 : _c.call(_b, body)) !== null && _d !== void 0 ? _d : body.errors) !== null && _e !== void 0 ? _e : {};
|
|
53
|
-
}
|
|
54
|
-
throw error;
|
|
55
|
-
}
|
|
27
|
+
async validateAsync(_value, state, context) {
|
|
28
|
+
const request = this.requestFactory();
|
|
29
|
+
const validateOnly = this.getAsyncValidationPaths(context.field, state);
|
|
30
|
+
request.setBody(context.payload);
|
|
31
|
+
request.setHeaders({
|
|
32
|
+
Accept: this.options.acceptHeader ?? 'application/json',
|
|
33
|
+
Precognition: 'true',
|
|
34
|
+
'Precognition-Validate-Only': validateOnly.join(',')
|
|
56
35
|
});
|
|
36
|
+
try {
|
|
37
|
+
await request.send({ resolveBody: false });
|
|
38
|
+
return {};
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
if (error instanceof ValidationException) {
|
|
42
|
+
const body = error.getBody();
|
|
43
|
+
return this.options.resolveErrors?.(body) ?? body.errors ?? {};
|
|
44
|
+
}
|
|
45
|
+
throw error;
|
|
46
|
+
}
|
|
57
47
|
}
|
|
58
48
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { BaseRule } from './BaseRule';
|
|
2
2
|
export class UrlRule extends BaseRule {
|
|
3
|
+
message;
|
|
3
4
|
constructor(message = 'Please enter a valid URL') {
|
|
4
5
|
super();
|
|
5
6
|
this.message = message;
|
|
@@ -12,7 +13,7 @@ export class UrlRule extends BaseRule {
|
|
|
12
13
|
new URL(value);
|
|
13
14
|
return true;
|
|
14
15
|
}
|
|
15
|
-
catch
|
|
16
|
+
catch {
|
|
16
17
|
return false;
|
|
17
18
|
}
|
|
18
19
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { ref, computed } from 'vue';
|
|
2
2
|
export class VueRequestBatchLoader {
|
|
3
|
+
inFlight = ref(0);
|
|
4
|
+
completed = ref(0);
|
|
5
|
+
expected = 0;
|
|
3
6
|
constructor(expectedRequests = 0) {
|
|
4
|
-
this.inFlight = ref(0);
|
|
5
|
-
this.completed = ref(0);
|
|
6
|
-
this.expected = 0;
|
|
7
7
|
this.expected = expectedRequests;
|
|
8
8
|
}
|
|
9
9
|
startBatch(count) {
|
|
@@ -1,12 +1,3 @@
|
|
|
1
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
1
|
import { computed, defineComponent, h } from 'vue';
|
|
11
2
|
import { RouterView, useRoute } from 'vue-router';
|
|
12
3
|
/**
|
|
@@ -75,7 +66,7 @@ export const RouteResourceBoundView = defineComponent({
|
|
|
75
66
|
return null;
|
|
76
67
|
for (const key of Object.keys(state)) {
|
|
77
68
|
const entry = state[key];
|
|
78
|
-
if (entry
|
|
69
|
+
if (entry?.error)
|
|
79
70
|
return entry.error;
|
|
80
71
|
}
|
|
81
72
|
return null;
|
|
@@ -84,21 +75,20 @@ export const RouteResourceBoundView = defineComponent({
|
|
|
84
75
|
const state = injectionState.value;
|
|
85
76
|
if (!state)
|
|
86
77
|
return false;
|
|
87
|
-
return Object.keys(state).some((key) =>
|
|
78
|
+
return Object.keys(state).some((key) => state[key]?.loading);
|
|
88
79
|
});
|
|
89
|
-
const refresh = () =>
|
|
80
|
+
const refresh = async () => {
|
|
90
81
|
const state = injectionState.value;
|
|
91
82
|
if (!state)
|
|
92
83
|
return;
|
|
93
|
-
const erroredProps = Object.keys(state).filter((key) =>
|
|
94
|
-
|
|
95
|
-
}
|
|
84
|
+
const erroredProps = Object.keys(state).filter((key) => state[key]?.error);
|
|
85
|
+
await Promise.all(erroredProps.map((propName) => route.meta.refresh?.(propName)));
|
|
86
|
+
};
|
|
96
87
|
/**
|
|
97
88
|
* Core render logic that decides which slot/component to show
|
|
98
89
|
* given the resolved Component and route from RouterView.
|
|
99
90
|
*/
|
|
100
91
|
function renderContent(Component, resolvedRoute) {
|
|
101
|
-
var _a, _b;
|
|
102
92
|
const isLazy = resolvedRoute.meta._lazy !== false;
|
|
103
93
|
if (isLazy) {
|
|
104
94
|
if (firstError.value) {
|
|
@@ -106,14 +96,14 @@ export const RouteResourceBoundView = defineComponent({
|
|
|
106
96
|
if (errorComponent) {
|
|
107
97
|
return h(errorComponent, { error: firstError.value, refresh });
|
|
108
98
|
}
|
|
109
|
-
return
|
|
99
|
+
return slots['error']?.({ error: firstError.value, refresh });
|
|
110
100
|
}
|
|
111
101
|
if (anyLoading.value) {
|
|
112
102
|
const loadingComponent = resolvedRoute.meta._loadingComponent;
|
|
113
103
|
if (loadingComponent) {
|
|
114
104
|
return h(loadingComponent);
|
|
115
105
|
}
|
|
116
|
-
return
|
|
106
|
+
return slots['loading']?.();
|
|
117
107
|
}
|
|
118
108
|
}
|
|
119
109
|
if (slots['default']) {
|
|
@@ -1,20 +1,10 @@
|
|
|
1
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
1
|
export class RouteResourceRequestResolver {
|
|
2
|
+
request;
|
|
11
3
|
constructor(request) {
|
|
12
4
|
this.request = request;
|
|
13
5
|
}
|
|
14
|
-
resolve() {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
return response.getData();
|
|
18
|
-
});
|
|
6
|
+
async resolve() {
|
|
7
|
+
const response = await this.request.send();
|
|
8
|
+
return response.getData();
|
|
19
9
|
}
|
|
20
10
|
}
|
|
@@ -15,27 +15,28 @@ import { markRaw } from 'vue';
|
|
|
15
15
|
*/
|
|
16
16
|
export function defineRoute() {
|
|
17
17
|
return function (route) {
|
|
18
|
-
var _a, _b, _c;
|
|
19
18
|
const originalProps = route.props;
|
|
20
19
|
if (route.errorComponent) {
|
|
21
|
-
route.meta =
|
|
20
|
+
route.meta = route.meta ?? {};
|
|
22
21
|
route.meta._errorComponent = markRaw(route.errorComponent);
|
|
23
22
|
delete route.errorComponent;
|
|
24
23
|
}
|
|
25
24
|
if (route.loadingComponent) {
|
|
26
|
-
route.meta =
|
|
25
|
+
route.meta = route.meta ?? {};
|
|
27
26
|
route.meta._loadingComponent = markRaw(route.loadingComponent);
|
|
28
27
|
delete route.loadingComponent;
|
|
29
28
|
}
|
|
30
29
|
if (route.lazy !== undefined) {
|
|
31
|
-
route.meta =
|
|
30
|
+
route.meta = route.meta ?? {};
|
|
32
31
|
route.meta._lazy = route.lazy;
|
|
33
32
|
delete route.lazy;
|
|
34
33
|
}
|
|
35
34
|
route.props = (to) => {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
35
|
+
const baseProps = typeof originalProps === 'function' ? originalProps(to) : originalProps === true ? to.params : (originalProps ?? {});
|
|
36
|
+
return {
|
|
37
|
+
...baseProps,
|
|
38
|
+
...(to.meta._injectedProps ?? {})
|
|
39
|
+
};
|
|
39
40
|
};
|
|
40
41
|
return route;
|
|
41
42
|
};
|
|
@@ -1,12 +1,3 @@
|
|
|
1
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
1
|
import { reactive } from 'vue';
|
|
11
2
|
/**
|
|
12
3
|
* Installs the runtime part:
|
|
@@ -22,7 +13,7 @@ import { reactive } from 'vue';
|
|
|
22
13
|
*/
|
|
23
14
|
export function installRouteInjection(router) {
|
|
24
15
|
const cache = {};
|
|
25
|
-
router.beforeResolve((to) =>
|
|
16
|
+
router.beforeResolve(async (to) => {
|
|
26
17
|
console.log('[Route Injection] Resolving route injections...');
|
|
27
18
|
if (!to.meta._injectedProps) {
|
|
28
19
|
to.meta._injectedProps = reactive({});
|
|
@@ -60,15 +51,15 @@ export function installRouteInjection(router) {
|
|
|
60
51
|
state[propName] = reactive({ loading: false, error: null });
|
|
61
52
|
}
|
|
62
53
|
// Define the refresh logic for this specific prop (always fetches fresh data)
|
|
63
|
-
const resolveProp = (options) =>
|
|
54
|
+
const resolveProp = async (options) => {
|
|
64
55
|
const propState = to.meta._injectionState[propName];
|
|
65
|
-
if (!
|
|
56
|
+
if (!options?.silent) {
|
|
66
57
|
propState.loading = true;
|
|
67
58
|
}
|
|
68
59
|
propState.error = null;
|
|
69
60
|
try {
|
|
70
61
|
const resolver = cfg.resolve(paramValue);
|
|
71
|
-
let payload =
|
|
62
|
+
let payload = await resolver.resolve();
|
|
72
63
|
if (typeof cfg.getter === 'function') {
|
|
73
64
|
payload = cfg.getter(payload);
|
|
74
65
|
}
|
|
@@ -86,7 +77,7 @@ export function installRouteInjection(router) {
|
|
|
86
77
|
finally {
|
|
87
78
|
propState.loading = false;
|
|
88
79
|
}
|
|
89
|
-
}
|
|
80
|
+
};
|
|
90
81
|
resolvers[propName] = resolveProp;
|
|
91
82
|
// Reuse cached value if the param hasn't changed (e.g. navigating between child routes)
|
|
92
83
|
const cached = cache[propName];
|
|
@@ -99,14 +90,14 @@ export function installRouteInjection(router) {
|
|
|
99
90
|
// Set loading immediately and queue resolver (non-blocking)
|
|
100
91
|
const injectionState = to.meta._injectionState;
|
|
101
92
|
injectionState[propName].loading = true;
|
|
102
|
-
pendingResolvers.push(() =>
|
|
93
|
+
pendingResolvers.push(async () => {
|
|
103
94
|
try {
|
|
104
|
-
|
|
95
|
+
await resolveProp();
|
|
105
96
|
}
|
|
106
97
|
catch (e) {
|
|
107
98
|
console.error(`[Route Injection] Failed to resolve prop "${propName}"`, e);
|
|
108
99
|
}
|
|
109
|
-
})
|
|
100
|
+
});
|
|
110
101
|
console.debug(`[Route Injection] Queued resolution for prop "${propName}" for route "${record.path}"`);
|
|
111
102
|
}
|
|
112
103
|
}
|
|
@@ -118,16 +109,16 @@ export function installRouteInjection(router) {
|
|
|
118
109
|
}
|
|
119
110
|
// Attach the resolvers and a global refresh helper to the route meta
|
|
120
111
|
to.meta['_injectedResolvers'] = resolvers;
|
|
121
|
-
to.meta['refresh'] = (propName, options) =>
|
|
112
|
+
to.meta['refresh'] = async (propName, options) => {
|
|
122
113
|
if (resolvers[propName]) {
|
|
123
|
-
return
|
|
114
|
+
return await resolvers[propName](options);
|
|
124
115
|
}
|
|
125
116
|
console.warn(`[Route Injection] No resolver found for "${propName}"`);
|
|
126
117
|
return undefined;
|
|
127
|
-
}
|
|
118
|
+
};
|
|
128
119
|
// Fire pending resolvers without blocking navigation
|
|
129
120
|
if (pendingResolvers.length > 0) {
|
|
130
121
|
Promise.all(pendingResolvers.map((fn) => fn()));
|
|
131
122
|
}
|
|
132
|
-
})
|
|
123
|
+
});
|
|
133
124
|
}
|
|
@@ -1,29 +1,17 @@
|
|
|
1
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
1
|
import { computed } from 'vue';
|
|
11
2
|
import { useRoute } from 'vue-router';
|
|
12
3
|
export function useRouteResource(propName) {
|
|
13
4
|
const route = useRoute();
|
|
14
|
-
const refresh = (options) =>
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
});
|
|
5
|
+
const refresh = async (options) => {
|
|
6
|
+
return await route.meta.refresh?.(propName, options);
|
|
7
|
+
};
|
|
18
8
|
const isLoading = computed(() => {
|
|
19
|
-
var _a, _b;
|
|
20
9
|
const state = route.meta._injectionState;
|
|
21
|
-
return
|
|
10
|
+
return state?.[propName]?.loading ?? false;
|
|
22
11
|
});
|
|
23
12
|
const error = computed(() => {
|
|
24
|
-
var _a, _b;
|
|
25
13
|
const state = route.meta._injectionState;
|
|
26
|
-
return
|
|
14
|
+
return state?.[propName]?.error ?? null;
|
|
27
15
|
});
|
|
28
16
|
return { refresh, isLoading, error };
|
|
29
17
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type PersistenceDriver } from '../../persistenceDrivers';
|
|
2
2
|
export interface StateOptions {
|
|
3
3
|
persist?: boolean;
|
|
4
|
+
persistKey?: string;
|
|
4
5
|
persistSuffix?: string;
|
|
5
6
|
}
|
|
6
7
|
/** Generic type for change handlers. */
|
|
@@ -24,6 +25,7 @@ export declare abstract class State<T extends object> {
|
|
|
24
25
|
private _resetHandlers;
|
|
25
26
|
private _watchIdCounter;
|
|
26
27
|
protected constructor(initial: T, options?: StateOptions);
|
|
28
|
+
private resolvePersistKey;
|
|
27
29
|
/**
|
|
28
30
|
* Safe deep clone that preserves types
|
|
29
31
|
*/
|
package/dist/vue/state/State.js
CHANGED
|
@@ -15,15 +15,19 @@ function getNestedValue(root, pathParts) {
|
|
|
15
15
|
return current;
|
|
16
16
|
}
|
|
17
17
|
export class State {
|
|
18
|
+
properties;
|
|
19
|
+
_initial;
|
|
20
|
+
_persist;
|
|
21
|
+
_persistKey;
|
|
22
|
+
_driver;
|
|
23
|
+
_stateProxy = null;
|
|
24
|
+
_watchStopFunctions = new Map();
|
|
25
|
+
_resetHandlers = new Map();
|
|
26
|
+
_watchIdCounter = 0;
|
|
18
27
|
constructor(initial, options) {
|
|
19
|
-
this._stateProxy = null;
|
|
20
|
-
this._watchStopFunctions = new Map();
|
|
21
|
-
this._resetHandlers = new Map();
|
|
22
|
-
this._watchIdCounter = 0;
|
|
23
28
|
this._initial = initial;
|
|
24
|
-
this._persist = !!
|
|
25
|
-
|
|
26
|
-
this._persistKey = className + ((options === null || options === void 0 ? void 0 : options.persistSuffix) ? `_${options.persistSuffix}` : '');
|
|
29
|
+
this._persist = !!options?.persist;
|
|
30
|
+
this._persistKey = this.resolvePersistKey(options);
|
|
27
31
|
this._driver = this.getPersistenceDriver();
|
|
28
32
|
let loaded = null;
|
|
29
33
|
if (this._persist) {
|
|
@@ -38,7 +42,7 @@ export class State {
|
|
|
38
42
|
}
|
|
39
43
|
}
|
|
40
44
|
}
|
|
41
|
-
const base = loaded
|
|
45
|
+
const base = loaded ?? initial;
|
|
42
46
|
this.properties = {};
|
|
43
47
|
const keys = Object.keys(base);
|
|
44
48
|
for (const k of keys) {
|
|
@@ -56,6 +60,15 @@ export class State {
|
|
|
56
60
|
});
|
|
57
61
|
}
|
|
58
62
|
}
|
|
63
|
+
resolvePersistKey(options) {
|
|
64
|
+
if (this._persist && !options?.persistKey) {
|
|
65
|
+
throw new Error('State persistence requires a stable persistKey option.');
|
|
66
|
+
}
|
|
67
|
+
if (!options?.persistKey) {
|
|
68
|
+
return '';
|
|
69
|
+
}
|
|
70
|
+
return options.persistSuffix ? `${options.persistKey}_${options.persistSuffix}` : options.persistKey;
|
|
71
|
+
}
|
|
59
72
|
/**
|
|
60
73
|
* Safe deep clone that preserves types
|
|
61
74
|
*/
|
|
@@ -115,7 +128,7 @@ export class State {
|
|
|
115
128
|
;
|
|
116
129
|
handler(path, this.export());
|
|
117
130
|
};
|
|
118
|
-
if (options
|
|
131
|
+
if (options?.executeOnReset) {
|
|
119
132
|
resetHandlers.push(pathHandler);
|
|
120
133
|
}
|
|
121
134
|
const stop = this.setupWatcher(path, pathHandler, options);
|
|
@@ -124,7 +137,7 @@ export class State {
|
|
|
124
137
|
}
|
|
125
138
|
else {
|
|
126
139
|
const pathHandler = handler;
|
|
127
|
-
if (options
|
|
140
|
+
if (options?.executeOnReset) {
|
|
128
141
|
resetHandlers.push(() => pathHandler(undefined, undefined));
|
|
129
142
|
}
|
|
130
143
|
const stop = this.setupWatcher(paths, pathHandler, options);
|
|
@@ -144,7 +157,7 @@ export class State {
|
|
|
144
157
|
*/
|
|
145
158
|
setupWatcher(path, handler, options) {
|
|
146
159
|
const pathParts = path.split('.');
|
|
147
|
-
const debouncedHandler =
|
|
160
|
+
const debouncedHandler = options?.debounce && options.debounce > 0 ? debounce(handler, options.debounce) : undefined;
|
|
148
161
|
const effectiveHandler = debouncedHandler || handler;
|
|
149
162
|
if (pathParts.length === 1 && path in this.properties) {
|
|
150
163
|
const key = path;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blueprint-ts/core",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.0.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -85,7 +85,7 @@
|
|
|
85
85
|
},
|
|
86
86
|
"scripts": {
|
|
87
87
|
"dev": "vite",
|
|
88
|
-
"build": "run-p type-check build:package
|
|
88
|
+
"build": "run-p type-check build:package",
|
|
89
89
|
"build:package": "tsc -p tsconfig.build.json",
|
|
90
90
|
"preview": "vite preview",
|
|
91
91
|
"test": "vitest",
|
|
@@ -103,37 +103,37 @@
|
|
|
103
103
|
"prepare": "npm run build:package"
|
|
104
104
|
},
|
|
105
105
|
"devDependencies": {
|
|
106
|
+
"@eslint/js": "^10.0.1",
|
|
106
107
|
"@rushstack/eslint-patch": "^1.3.3",
|
|
107
108
|
"@tsconfig/node20": "^20.1.2",
|
|
108
|
-
"@types/jsdom": "^
|
|
109
|
+
"@types/jsdom": "^28.0.3",
|
|
109
110
|
"@types/lodash-es": "^4.17.12",
|
|
110
|
-
"@types/node": "^
|
|
111
|
-
"@types/qs": "^6.
|
|
112
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
113
|
-
"@typescript-eslint/parser": "^8.
|
|
114
|
-
"@typescript-eslint/typescript-estree": "^8.
|
|
115
|
-
"@vitejs/plugin-vue": "^
|
|
116
|
-
"@
|
|
117
|
-
"@
|
|
118
|
-
"
|
|
119
|
-
"
|
|
120
|
-
"eslint": "^9.0.0",
|
|
111
|
+
"@types/node": "^26.0.0",
|
|
112
|
+
"@types/qs": "^6.15.1",
|
|
113
|
+
"@typescript-eslint/eslint-plugin": "^8.62.0",
|
|
114
|
+
"@typescript-eslint/parser": "^8.62.0",
|
|
115
|
+
"@typescript-eslint/typescript-estree": "^8.62.0",
|
|
116
|
+
"@vitejs/plugin-vue": "^6.0.7",
|
|
117
|
+
"@vitest/coverage-v8": "^4.1.9",
|
|
118
|
+
"@vue/eslint-config-typescript": "^14.9.0",
|
|
119
|
+
"autoprefixer": "^10.5.0",
|
|
120
|
+
"eslint": "^10.5.0",
|
|
121
121
|
"eslint-config-prettier": "^10.0.1",
|
|
122
|
-
"eslint-plugin-vue": "^9.
|
|
123
|
-
"jsdom": "^
|
|
124
|
-
"npm-run-all2": "^
|
|
125
|
-
"prettier": "^3.
|
|
126
|
-
"typescript": "^
|
|
127
|
-
"typescript-eslint": "^8.
|
|
128
|
-
"vite": "^
|
|
122
|
+
"eslint-plugin-vue": "^10.9.2",
|
|
123
|
+
"jsdom": "^29.1.1",
|
|
124
|
+
"npm-run-all2": "^9.0.2",
|
|
125
|
+
"prettier": "^3.8.4",
|
|
126
|
+
"typescript": "^6.0.3",
|
|
127
|
+
"typescript-eslint": "^8.62.0",
|
|
128
|
+
"vite": "^8.0.16",
|
|
129
129
|
"vitepress": "^1.6.3",
|
|
130
|
-
"vitest": "^
|
|
131
|
-
"vue": "^3.
|
|
132
|
-
"vue-router": "^
|
|
130
|
+
"vitest": "^4.1.9",
|
|
131
|
+
"vue": "^3.5.38",
|
|
132
|
+
"vue-router": "^5.1.0"
|
|
133
133
|
},
|
|
134
134
|
"dependencies": {
|
|
135
|
-
"lodash-es": "^4.
|
|
136
|
-
"qs": "^6.15.
|
|
137
|
-
"uuid": "^
|
|
135
|
+
"lodash-es": "^4.18.1",
|
|
136
|
+
"qs": "^6.15.2",
|
|
137
|
+
"uuid": "^14.0.1"
|
|
138
138
|
}
|
|
139
139
|
}
|