@platforma-sdk/ui-vue 1.43.21 → 1.43.29
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/.turbo/turbo-build.log +8 -8
- package/.turbo/turbo-type-check.log +1 -1
- package/CHANGELOG.md +14 -0
- package/dist/internal/createAppV1.js +12 -12
- package/dist/internal/createAppV1.js.map +1 -1
- package/dist/internal/createAppV2.d.ts +1 -1
- package/dist/internal/createAppV2.js +59 -57
- package/dist/internal/createAppV2.js.map +1 -1
- package/dist/utils.js +26 -24
- package/dist/utils.js.map +1 -1
- package/package.json +6 -6
- package/src/internal/createAppV1.ts +1 -1
- package/src/internal/createAppV2.ts +16 -6
- package/src/utils.ts +5 -0
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
WARN Issue while reading "/home/runner/_work/platforma/platforma/.npmrc". Failed to replace env in config: ${NPMJS_TOKEN}
|
|
2
2
|
|
|
3
|
-
> @platforma-sdk/ui-vue@1.43.
|
|
3
|
+
> @platforma-sdk/ui-vue@1.43.29 build /home/runner/_work/platforma/platforma/sdk/ui-vue
|
|
4
4
|
> ts-builder build --target browser-lib
|
|
5
5
|
|
|
6
6
|
Building browser-lib project...
|
|
@@ -23,8 +23,8 @@ computing gzip size...
|
|
|
23
23
|
[2mdist/[22m[36mcomponents/PlAgCellFile/PlAgCellFile.vue2.js [39m[1m[2m 0.11 kB[22m[1m[22m[2m │ gzip: 0.12 kB[22m[2m │ map: 0.10 kB[22m
|
|
24
24
|
[2mdist/[22m[36mcomponents/PlAgDataTable/PlAgRowCount.vue2.js [39m[1m[2m 0.11 kB[22m[1m[22m[2m │ gzip: 0.12 kB[22m[2m │ map: 0.10 kB[22m
|
|
25
25
|
[2mdist/[22m[36mcomponents/PlAgCsvExporter/PlAgCsvExporter.vue2.js [39m[1m[2m 0.12 kB[22m[1m[22m[2m │ gzip: 0.12 kB[22m[2m │ map: 0.11 kB[22m
|
|
26
|
-
[2mdist/[22m[36mcomponents/PlAgColumnHeader/PlAgColumnHeader.vue2.js [39m[1m[2m 0.12 kB[22m[1m[22m[2m │ gzip: 0.12 kB[22m[2m │ map: 0.11 kB[22m
|
|
27
26
|
[2mdist/[22m[36mcomponents/PlAgCellProgress/PlAgCellProgress.vue2.js [39m[1m[2m 0.12 kB[22m[1m[22m[2m │ gzip: 0.12 kB[22m[2m │ map: 0.11 kB[22m
|
|
27
|
+
[2mdist/[22m[36mcomponents/PlAgColumnHeader/PlAgColumnHeader.vue2.js [39m[1m[2m 0.12 kB[22m[1m[22m[2m │ gzip: 0.12 kB[22m[2m │ map: 0.11 kB[22m
|
|
28
28
|
[2mdist/[22m[36mcomponents/PlAgRowNumHeader.vue2.js [39m[1m[2m 0.12 kB[22m[1m[22m[2m │ gzip: 0.12 kB[22m[2m │ map: 0.11 kB[22m
|
|
29
29
|
[2mdist/[22m[36mcomponents/PlAgDataTable/PlAgOverlayLoading.vue2.js [39m[1m[2m 0.12 kB[22m[1m[22m[2m │ gzip: 0.12 kB[22m[2m │ map: 0.11 kB[22m
|
|
30
30
|
[2mdist/[22m[36mcomponents/PlAgRowNumCheckbox/PlAgRowNumCheckbox.vue2.js [39m[1m[2m 0.12 kB[22m[1m[22m[2m │ gzip: 0.12 kB[22m[2m │ map: 0.11 kB[22m
|
|
@@ -84,8 +84,8 @@ computing gzip size...
|
|
|
84
84
|
[2mdist/[22m[36mcomponents/PlMultiSequenceAlignment/PhylogeneticTree.vue.js [39m[1m[2m 0.30 kB[22m[1m[22m[2m │ gzip: 0.22 kB[22m[2m │ map: 0.11 kB[22m
|
|
85
85
|
[2mdist/[22m[36mnode_modules/.pnpm/semver@7.7.2/node_modules/semver/ranges/to-comparators.js [39m[1m[2m 0.30 kB[22m[1m[22m[2m │ gzip: 0.23 kB[22m[2m │ map: 0.78 kB[22m
|
|
86
86
|
[2mdist/[22m[36mcomponents/PlAnnotations/components/PlAnnotationsModal.vue.js [39m[1m[2m 0.31 kB[22m[1m[22m[2m │ gzip: 0.22 kB[22m[2m │ map: 0.11 kB[22m
|
|
87
|
-
[2mdist/[22m[36mcomponents/PlAnnotations/components/AnnotationsSidebar.vue.js [39m[1m[2m 0.31 kB[22m[1m[22m[2m │ gzip: 0.22 kB[22m[2m │ map: 0.11 kB[22m
|
|
88
87
|
[2mdist/[22m[36mcomponents/PlAgDataTable/PlAgDataTableSheets.vue.js [39m[1m[2m 0.31 kB[22m[1m[22m[2m │ gzip: 0.22 kB[22m[2m │ map: 0.11 kB[22m
|
|
88
|
+
[2mdist/[22m[36mcomponents/PlAnnotations/components/AnnotationsSidebar.vue.js [39m[1m[2m 0.31 kB[22m[1m[22m[2m │ gzip: 0.22 kB[22m[2m │ map: 0.11 kB[22m
|
|
89
89
|
[2mdist/[22m[36mnode_modules/.pnpm/semver@7.7.2/node_modules/semver/ranges/valid.js [39m[1m[2m 0.31 kB[22m[1m[22m[2m │ gzip: 0.22 kB[22m[2m │ map: 0.76 kB[22m
|
|
90
90
|
[2mdist/[22m[36mcomponents/PlAgGridColumnManager/PlAgGridColumnManager.vue.js [39m[1m[2m 0.32 kB[22m[1m[22m[2m │ gzip: 0.23 kB[22m[2m │ map: 0.12 kB[22m
|
|
91
91
|
[2mdist/[22m[36mnode_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/satisfies.js [39m[1m[2m 0.32 kB[22m[1m[22m[2m │ gzip: 0.23 kB[22m[2m │ map: 0.74 kB[22m
|
|
@@ -155,9 +155,9 @@ computing gzip size...
|
|
|
155
155
|
[2mdist/[22m[36mcomponents/PlAgDataTable/PlAgOverlayLoading.vue.js [39m[1m[2m 1.30 kB[22m[1m[22m[2m │ gzip: 0.66 kB[22m[2m │ map: 1.40 kB[22m
|
|
156
156
|
[2mdist/[22m[36mcreateModel.js [39m[1m[2m 1.44 kB[22m[1m[22m[2m │ gzip: 0.66 kB[22m[2m │ map: 3.91 kB[22m
|
|
157
157
|
[2mdist/[22m[36mcomponents/PlAgDataTable/types.js [39m[1m[2m 1.45 kB[22m[1m[22m[2m │ gzip: 0.57 kB[22m[2m │ map: 9.46 kB[22m
|
|
158
|
-
[2mdist/[22m[36mutils.js [39m[1m[2m 1.51 kB[22m[1m[22m[2m │ gzip: 0.69 kB[22m[2m │ map: 3.53 kB[22m
|
|
159
158
|
[2mdist/[22m[36mnode_modules/.pnpm/semver@7.7.2/node_modules/semver/ranges/outside.js [39m[1m[2m 1.55 kB[22m[1m[22m[2m │ gzip: 0.65 kB[22m[2m │ map: 3.99 kB[22m
|
|
160
159
|
[2mdist/[22m[36mplugins/Monetization/UserCabinetCard.vue3.js [39m[1m[2m 1.55 kB[22m[1m[22m[2m │ gzip: 0.77 kB[22m[2m │ map: 0.11 kB[22m
|
|
160
|
+
[2mdist/[22m[36mutils.js [39m[1m[2m 1.57 kB[22m[1m[22m[2m │ gzip: 0.72 kB[22m[2m │ map: 3.81 kB[22m
|
|
161
161
|
[2mdist/[22m[36mcomponents/PlAgCsvExporter/export-csv.js [39m[1m[2m 1.60 kB[22m[1m[22m[2m │ gzip: 0.73 kB[22m[2m │ map: 3.72 kB[22m
|
|
162
162
|
[2mdist/[22m[36mcomponents/PlAgDataTable/sources/focus-row.js [39m[1m[2m 1.62 kB[22m[1m[22m[2m │ gzip: 0.77 kB[22m[2m │ map: 2.65 kB[22m
|
|
163
163
|
[2mdist/[22m[36maggrid.js [39m[1m[2m 1.65 kB[22m[1m[22m[2m │ gzip: 0.79 kB[22m[2m │ map: 3.09 kB[22m
|
|
@@ -203,10 +203,10 @@ computing gzip size...
|
|
|
203
203
|
[2mdist/[22m[36mcomponents/BlockLayout.vue2.js [39m[1m[2m 4.96 kB[22m[1m[22m[2m │ gzip: 1.83 kB[22m[2m │ map: 2.96 kB[22m
|
|
204
204
|
[2mdist/[22m[36mcomponents/PlAnnotations/components/FilterSidebar.vue3.js [39m[1m[2m 5.48 kB[22m[1m[22m[2m │ gzip: 1.59 kB[22m[2m │ map: 0.11 kB[22m
|
|
205
205
|
[2mdist/[22m[36mcomponents/PlAnnotations/components/AnnotationsSidebar.vue3.js [39m[1m[2m 5.67 kB[22m[1m[22m[2m │ gzip: 1.67 kB[22m[2m │ map: 0.11 kB[22m
|
|
206
|
-
[2mdist/[22m[36minternal/createAppV1.js [39m[1m[2m 5.
|
|
206
|
+
[2mdist/[22m[36minternal/createAppV1.js [39m[1m[2m 5.81 kB[22m[1m[22m[2m │ gzip: 1.85 kB[22m[2m │ map: 15.33 kB[22m
|
|
207
207
|
[2mdist/[22m[36mcomponents/PlTableFilters/PlTableFiltersV2.vue2.js [39m[1m[2m 6.15 kB[22m[1m[22m[2m │ gzip: 2.03 kB[22m[2m │ map: 9.27 kB[22m
|
|
208
208
|
[2mdist/[22m[36mnode_modules/.pnpm/semver@7.7.2/node_modules/semver/classes/semver.js [39m[1m[2m 6.70 kB[22m[1m[22m[2m │ gzip: 1.86 kB[22m[2m │ map: 15.20 kB[22m
|
|
209
|
-
[2mdist/[22m[36minternal/createAppV2.js [39m[1m[2m 6.
|
|
209
|
+
[2mdist/[22m[36minternal/createAppV2.js [39m[1m[2m 6.99 kB[22m[1m[22m[2m │ gzip: 2.44 kB[22m[2m │ map: 19.37 kB[22m
|
|
210
210
|
[2mdist/[22m[36mcomponents/PlAgDataTable/sources/table-source-v2.js [39m[1m[2m 7.38 kB[22m[1m[22m[2m │ gzip: 2.68 kB[22m[2m │ map: 22.27 kB[22m
|
|
211
211
|
[2mdist/[22m[36mcomponents/PlTableFilters/PlTableFilterEntryV2.vue.js [39m[1m[2m 7.41 kB[22m[1m[22m[2m │ gzip: 1.62 kB[22m[2m │ map: 6.15 kB[22m
|
|
212
212
|
[2mdist/[22m[36mnode_modules/.pnpm/semver@7.7.2/node_modules/semver/classes/range.js [39m[1m[2m 7.70 kB[22m[1m[22m[2m │ gzip: 2.49 kB[22m[2m │ map: 25.65 kB[22m
|
|
@@ -223,7 +223,7 @@ computing gzip size...
|
|
|
223
223
|
[2mdist/[22m[36mcomponents/PlAgRowNumHeader.vue.js [39m[1m[2m 44.67 kB[22m[1m[22m[2m │ gzip: 29.30 kB[22m[2m │ map: 3.70 kB[22m
|
|
224
224
|
[2mdist/[22m[36mAgGridVue/useAgGridOptions.js [39m[1m[2m 49.30 kB[22m[1m[22m[2m │ gzip: 30.16 kB[22m[2m │ map: 16.35 kB[22m
|
|
225
225
|
[2mdist/[22m[36mcomponents/PlAgDataTable/PlAgDataTableV2.vue2.js [39m[1m[2m 50.39 kB[22m[1m[22m[2m │ gzip: 31.05 kB[22m[2m │ map: 33.70 kB[22m
|
|
226
|
-
[vite:dts] Declaration files built in
|
|
226
|
+
[vite:dts] Declaration files built in 12653ms.
|
|
227
227
|
|
|
228
|
-
[32m✓ built in
|
|
228
|
+
[32m✓ built in 15.64s[39m
|
|
229
229
|
Build completed successfully
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
WARN Issue while reading "/home/runner/_work/platforma/platforma/.npmrc". Failed to replace env in config: ${NPMJS_TOKEN}
|
|
2
2
|
|
|
3
|
-
> @platforma-sdk/ui-vue@1.43.
|
|
3
|
+
> @platforma-sdk/ui-vue@1.43.29 type-check /home/runner/_work/platforma/platforma/sdk/ui-vue
|
|
4
4
|
> ts-builder types --target browser-lib
|
|
5
5
|
|
|
6
6
|
↳ vue-tsc.js --noEmit --project ./tsconfig.json
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# @platforma-sdk/ui-vue
|
|
2
2
|
|
|
3
|
+
## 1.43.29
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- @platforma-sdk/model@1.43.29
|
|
8
|
+
- @milaboratories/uikit@2.4.20
|
|
9
|
+
|
|
10
|
+
## 1.43.28
|
|
11
|
+
|
|
12
|
+
### Patch Changes
|
|
13
|
+
|
|
14
|
+
- d390d04: Fix setting args on outputs change
|
|
15
|
+
- d390d04: Fix [sdk/ui] Broken error propagation: block errors are not showing anymore
|
|
16
|
+
|
|
3
17
|
## 1.43.21
|
|
4
18
|
|
|
5
19
|
### Patch Changes
|
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
import { tap as M } from "../lib/util/helpers/dist/utils.js";
|
|
2
2
|
import { isJsonEqual as n, deepClone as v } from "../lib/util/helpers/dist/objects.js";
|
|
3
3
|
import "../lib/util/helpers/dist/test_timeouts.js";
|
|
4
|
-
import { reactive as
|
|
4
|
+
import { reactive as f, nextTick as h, computed as s, watch as E } from "vue";
|
|
5
5
|
import { createModel as m } from "../createModel.js";
|
|
6
6
|
import { createAppModel as x } from "./createAppModel.js";
|
|
7
7
|
import { parseQuery as N } from "../urls.js";
|
|
8
8
|
import { MultiError as q, unwrapValueOrErrors as T } from "../utils.js";
|
|
9
|
-
import { useDebounceFn as
|
|
9
|
+
import { useDebounceFn as S } from "@vueuse/core";
|
|
10
10
|
function G(i, a, g) {
|
|
11
11
|
const c = (e, ...t) => {
|
|
12
12
|
g.debug && console.log(`%c>>> %c${e}`, "color: orange; font-weight: bold", "color: orange", ...t);
|
|
13
|
-
}, r =
|
|
13
|
+
}, r = f({
|
|
14
14
|
args: Object.freeze(i.args),
|
|
15
15
|
outputs: Object.freeze(i.outputs),
|
|
16
16
|
ui: Object.freeze(i.ui),
|
|
17
17
|
navigationState: Object.freeze(i.navigationState)
|
|
18
|
-
}), u = g.debounceSpan ?? 200, l = M(g.debounceMaxWait ?? 0, (e) => e < 2e4 ? 2e4 : e < u ? u * 100 : e), b =
|
|
18
|
+
}), u = g.debounceSpan ?? 200, l = M(g.debounceMaxWait ?? 0, (e) => e < 2e4 ? 2e4 : e < u ? u * 100 : e), b = S((e) => {
|
|
19
19
|
n(e, r.args) || a.setBlockArgs(e);
|
|
20
|
-
}, u, { maxWait: l }), j =
|
|
20
|
+
}, u, { maxWait: l }), j = S((e) => {
|
|
21
21
|
n(e, r.ui) || a.setBlockUiState(e);
|
|
22
|
-
}, u, { maxWait: l }), O =
|
|
22
|
+
}, u, { maxWait: l }), O = S((e, t) => {
|
|
23
23
|
(!n(e, r.args) || !n(t, r.ui)) && a.setBlockArgsAndUiState(e, t);
|
|
24
24
|
}, u, { maxWait: l });
|
|
25
25
|
a.onStateUpdates(async (e) => {
|
|
@@ -27,7 +27,7 @@ function G(i, a, g) {
|
|
|
27
27
|
t.key === "args" && !n(r.args, t.value) && (r.args = Object.freeze(t.value), c("args patch", r.args)), t.key === "ui" && !n(r.ui, t.value) && (r.ui = Object.freeze(t.value), c("ui patch", r.ui)), t.key === "outputs" && !n(r.outputs, t.value) && (r.outputs = Object.freeze(t.value), c("outputs patch", r.outputs)), t.key === "navigationState" && !n(r.navigationState, t.value) && (r.navigationState = Object.freeze(t.value), c("navigationState patch", r.navigationState));
|
|
28
28
|
}), await h();
|
|
29
29
|
});
|
|
30
|
-
const k = () => v(r.args), A = () => v(r.ui),
|
|
30
|
+
const k = () => v(r.args), A = () => v(r.ui), d = () => v(r.navigationState), w = {
|
|
31
31
|
createArgsModel(e = {}) {
|
|
32
32
|
return m({
|
|
33
33
|
get() {
|
|
@@ -61,7 +61,7 @@ function G(i, a, g) {
|
|
|
61
61
|
* @returns {OptionalResult<UnwrapOutputs<Outputs, K>>}
|
|
62
62
|
*/
|
|
63
63
|
useOutputs(...e) {
|
|
64
|
-
const t =
|
|
64
|
+
const t = f({
|
|
65
65
|
errors: void 0,
|
|
66
66
|
value: void 0
|
|
67
67
|
});
|
|
@@ -123,7 +123,7 @@ function G(i, a, g) {
|
|
|
123
123
|
* @returns A promise resolving after the update is applied.
|
|
124
124
|
*/
|
|
125
125
|
updateNavigationState(e) {
|
|
126
|
-
const t =
|
|
126
|
+
const t = d();
|
|
127
127
|
return e(t), a.setNavigationState(t);
|
|
128
128
|
},
|
|
129
129
|
/**
|
|
@@ -133,14 +133,14 @@ function G(i, a, g) {
|
|
|
133
133
|
* @returns A promise resolving after the navigation state is updated.
|
|
134
134
|
*/
|
|
135
135
|
navigateTo(e) {
|
|
136
|
-
const t =
|
|
136
|
+
const t = d();
|
|
137
137
|
return t.href = e, a.setNavigationState(t);
|
|
138
138
|
}
|
|
139
139
|
}, U = s(() => {
|
|
140
140
|
const e = Object.entries(r.outputs).map(([t, o]) => [t, o.ok && o.value !== void 0 ? o.value : void 0]);
|
|
141
141
|
return Object.fromEntries(e);
|
|
142
142
|
}), z = s(() => {
|
|
143
|
-
const e = Object.entries(r.outputs).map(([t, o]) => [t, o &&
|
|
143
|
+
const e = Object.entries(r.outputs).map(([t, o]) => [t, o && o.ok === !1 ? new q(o.errors) : void 0]);
|
|
144
144
|
return Object.fromEntries(e);
|
|
145
145
|
}), B = {
|
|
146
146
|
snapshot: r,
|
|
@@ -162,7 +162,7 @@ function G(i, a, g) {
|
|
|
162
162
|
outputErrors: z
|
|
163
163
|
}
|
|
164
164
|
);
|
|
165
|
-
return
|
|
165
|
+
return f(Object.assign(y, w, B));
|
|
166
166
|
}
|
|
167
167
|
export {
|
|
168
168
|
G as createAppV1
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createAppV1.js","sources":["../../src/internal/createAppV1.ts"],"sourcesContent":["import { deepClone, isJsonEqual, tap } from '@milaboratories/helpers';\nimport type { Mutable } from '@milaboratories/helpers';\nimport type { NavigationState, BlockOutputsBase, BlockState, PlatformaV1 } from '@platforma-sdk/model';\nimport { reactive, nextTick, computed, watch } from 'vue';\nimport type { StateModelOptions, UnwrapOutputs, OptionalResult, OutputValues, OutputErrors, AppSettings } from '../types';\nimport { createModel } from '../createModel';\nimport { createAppModel } from './createAppModel';\nimport { parseQuery } from '../urls';\nimport { MultiError, unwrapValueOrErrors } from '../utils';\nimport { useDebounceFn } from '@vueuse/core';\n/**\n * Creates an application instance with reactive state management, outputs, and methods for state updates and navigation.\n *\n * @template Args - The type of arguments used in the application.\n * @template Outputs - The type of block outputs extending `BlockOutputsBase`.\n * @template UiState - The type of the UI state.\n * @template Href - The type of navigation href, defaulting to a string starting with `/`.\n *\n * @param state - Initial state of the application, including args, outputs, UI state, and navigation state.\n * @param platforma - A platform interface for interacting with block states.\n * @param settings - Application settings, such as debug flags.\n *\n * @returns A reactive application object with methods, getters, and state.\n */\nexport function createAppV1<\n Args = unknown,\n Outputs extends BlockOutputsBase = BlockOutputsBase,\n UiState = unknown,\n Href extends `/${string}` = `/${string}`,\n>(\n state: BlockState<Args, Outputs, UiState, Href>,\n platforma: PlatformaV1<Args, Outputs, UiState, Href>,\n settings: AppSettings,\n) {\n type AppModel = {\n args: Args;\n ui: UiState;\n };\n\n const log = (msg: string, ...rest: unknown[]) => {\n if (settings.debug) {\n console.log(`%c>>> %c${msg}`, 'color: orange; font-weight: bold', 'color: orange', ...rest);\n }\n };\n\n /**\n * Reactive snapshot of the application state, including args, outputs, UI state, and navigation state.\n */\n const snapshot = reactive({\n args: Object.freeze(state.args),\n outputs: Object.freeze(state.outputs),\n ui: Object.freeze(state.ui),\n navigationState: Object.freeze(state.navigationState) as NavigationState<Href>,\n }) as {\n args: Readonly<Args>;\n outputs: Partial<Readonly<Outputs>>;\n ui: Readonly<UiState>;\n navigationState: Readonly<NavigationState<Href>>;\n };\n\n const debounceSpan = settings.debounceSpan ?? 200;\n\n const maxWait = tap(settings.debounceMaxWait ?? 0, (v) => v < 20_000 ? 20_000 : v < debounceSpan ? debounceSpan * 100 : v);\n\n const setBlockArgs = useDebounceFn((args: Args) => {\n if (!isJsonEqual(args, snapshot.args)) {\n platforma.setBlockArgs(args);\n }\n }, debounceSpan, { maxWait });\n\n const setBlockUiState = useDebounceFn((ui: UiState) => {\n if (!isJsonEqual(ui, snapshot.ui)) {\n platforma.setBlockUiState(ui);\n }\n }, debounceSpan, { maxWait });\n\n const setBlockArgsAndUiState = useDebounceFn((args: Args, ui: UiState) => {\n if (!isJsonEqual(args, snapshot.args) || !isJsonEqual(ui, snapshot.ui)) {\n platforma.setBlockArgsAndUiState(args, ui);\n }\n }, debounceSpan, { maxWait });\n\n (platforma as unknown as PlatformaV1<Args, Outputs, UiState, Href>).onStateUpdates(async (updates) => {\n updates.forEach((patch) => {\n if (patch.key === 'args' && !isJsonEqual(snapshot.args, patch.value)) {\n snapshot.args = Object.freeze(patch.value);\n log('args patch', snapshot.args);\n }\n\n if (patch.key === 'ui' && !isJsonEqual(snapshot.ui, patch.value)) {\n snapshot.ui = Object.freeze(patch.value);\n log('ui patch', snapshot.ui);\n }\n\n if (patch.key === 'outputs' && !isJsonEqual(snapshot.outputs, patch.value)) {\n snapshot.outputs = Object.freeze(patch.value);\n log('outputs patch', snapshot.outputs);\n }\n\n if (patch.key === 'navigationState' && !isJsonEqual(snapshot.navigationState, patch.value)) {\n snapshot.navigationState = Object.freeze(patch.value);\n log('navigationState patch', snapshot.navigationState);\n }\n });\n\n await nextTick();\n });\n\n const cloneArgs = () => deepClone(snapshot.args) as Args;\n const cloneUiState = () => deepClone(snapshot.ui) as UiState;\n const cloneNavigationState = () => deepClone(snapshot.navigationState) as Mutable<NavigationState<Href>>;\n\n const methods = {\n createArgsModel<T = Args>(options: StateModelOptions<Args, T> = {}) {\n return createModel<T, Args>({\n get() {\n if (options.transform) {\n return options.transform(snapshot.args);\n }\n\n return snapshot.args as T;\n },\n validate: options.validate,\n autoSave: true,\n onSave(newArgs) {\n setBlockArgs(newArgs);\n },\n });\n },\n /**\n * defaultUiState is temporarily here, remove it after implementing initialUiState\n */\n createUiModel<T = UiState>(options: StateModelOptions<UiState, T> = {}, defaultUiState: () => UiState) {\n return createModel<T, UiState>({\n get() {\n if (options.transform) {\n return options.transform(snapshot.ui);\n }\n\n return (snapshot.ui ?? defaultUiState()) as T;\n },\n validate: options.validate,\n autoSave: true,\n onSave(newData) {\n setBlockUiState(newData);\n },\n });\n },\n /**\n * Note: Don't forget to list the output names, like: useOutputs('output1', 'output2', ...etc)\n * @param keys - List of output names\n * @returns {OptionalResult<UnwrapOutputs<Outputs, K>>}\n */\n useOutputs<K extends keyof Outputs>(...keys: K[]): OptionalResult<UnwrapOutputs<Outputs, K>> {\n const data = reactive({\n errors: undefined,\n value: undefined,\n });\n\n watch(\n () => snapshot.outputs,\n () => {\n try {\n Object.assign(data, {\n value: this.unwrapOutputs<K>(...keys),\n errors: undefined,\n });\n } catch (error) {\n Object.assign(data, {\n value: undefined,\n errors: [String(error)],\n });\n }\n },\n { immediate: true, deep: true },\n );\n\n return data as OptionalResult<UnwrapOutputs<Outputs, K>>;\n },\n /**\n * Retrieves the unwrapped values of outputs for the given keys.\n *\n * @template K - Keys of the outputs to unwrap.\n * @param keys - List of output names.\n * @throws Error if the outputs contain errors.\n * @returns An object with unwrapped output values.\n */\n unwrapOutputs<K extends keyof Outputs>(...keys: K[]): UnwrapOutputs<Outputs, K> {\n const outputs = snapshot.outputs;\n const entries = keys.map((key) => [key, unwrapValueOrErrors(outputs[key])]);\n return Object.fromEntries(entries);\n },\n /**\n * Updates the arguments state by applying a callback.\n *\n * @param cb - Callback to modify the current arguments.\n * @returns A promise resolving after the update is applied.\n */\n updateArgs(cb: (args: Args) => void) {\n const newArgs = cloneArgs();\n cb(newArgs);\n return platforma.setBlockArgs(newArgs);\n },\n /**\n * Updates the UI state by applying a callback.\n *\n * @param cb - Callback to modify the current UI state.\n * @returns A promise resolving after the update is applied.\n * @todo Make it mutable since there is already an initial one\n */\n updateUiState(cb: (args: UiState) => UiState): Promise<void> {\n const newUiState = cloneUiState();\n return platforma.setBlockUiState(cb(newUiState));\n },\n /**\n * Updates the navigation state by applying a callback.\n *\n * @param cb - Callback to modify the current navigation state.\n * @returns A promise resolving after the update is applied.\n */\n updateNavigationState(cb: (args: Mutable<NavigationState<Href>>) => void) {\n const newState = cloneNavigationState();\n cb(newState);\n return platforma.setNavigationState(newState);\n },\n /**\n * Navigates to a specific href by updating the navigation state.\n *\n * @param href - The target href to navigate to.\n * @returns A promise resolving after the navigation state is updated.\n */\n navigateTo(href: Href) {\n const newState = cloneNavigationState();\n newState.href = href;\n return platforma.setNavigationState(newState);\n },\n };\n\n const outputs = computed<OutputValues<Outputs>>(() => {\n const entries = Object.entries(snapshot.outputs).map(([k, vOrErr]) => [k, vOrErr.ok && vOrErr.value !== undefined ? vOrErr.value : undefined]);\n return Object.fromEntries(entries);\n });\n\n const outputErrors = computed<OutputErrors<Outputs>>(() => {\n const entries = Object.entries(snapshot.outputs).map(([k, vOrErr]) => [k, vOrErr && !vOrErr.ok ? new MultiError(vOrErr.errors) : undefined]);\n return Object.fromEntries(entries);\n });\n\n const getters = {\n snapshot,\n queryParams: computed(() => parseQuery<Href>(snapshot.navigationState.href)),\n href: computed(() => snapshot.navigationState.href),\n hasErrors: computed(() => Object.values(snapshot.outputs).some((v) => !v?.ok)),\n };\n\n const model = createAppModel(\n {\n get() {\n return { args: snapshot.args, ui: snapshot.ui } as AppModel;\n },\n autoSave: true,\n onSave(newData: AppModel) {\n setBlockArgsAndUiState(newData.args, newData.ui);\n },\n },\n {\n outputs,\n outputErrors,\n },\n settings,\n );\n\n return reactive(Object.assign(model, methods, getters));\n}\n\nexport type BaseAppV1<\n Args = unknown,\n Outputs extends BlockOutputsBase = BlockOutputsBase,\n UiState = unknown,\n Href extends `/${string}` = `/${string}`,\n> = ReturnType<typeof createAppV1<Args, Outputs, UiState, Href>>;\n"],"names":["createAppV1","state","platforma","settings","log","msg","rest","snapshot","reactive","debounceSpan","maxWait","tap","v","setBlockArgs","useDebounceFn","args","isJsonEqual","setBlockUiState","ui","setBlockArgsAndUiState","updates","patch","nextTick","cloneArgs","deepClone","cloneUiState","cloneNavigationState","methods","options","createModel","newArgs","defaultUiState","newData","keys","data","watch","error","outputs","entries","key","unwrapValueOrErrors","cb","newUiState","newState","href","computed","k","vOrErr","outputErrors","MultiError","getters","parseQuery","model","createAppModel"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"createAppV1.js","sources":["../../src/internal/createAppV1.ts"],"sourcesContent":["import { deepClone, isJsonEqual, tap } from '@milaboratories/helpers';\nimport type { Mutable } from '@milaboratories/helpers';\nimport type { NavigationState, BlockOutputsBase, BlockState, PlatformaV1 } from '@platforma-sdk/model';\nimport { reactive, nextTick, computed, watch } from 'vue';\nimport type { StateModelOptions, UnwrapOutputs, OptionalResult, OutputValues, OutputErrors, AppSettings } from '../types';\nimport { createModel } from '../createModel';\nimport { createAppModel } from './createAppModel';\nimport { parseQuery } from '../urls';\nimport { MultiError, unwrapValueOrErrors } from '../utils';\nimport { useDebounceFn } from '@vueuse/core';\n/**\n * Creates an application instance with reactive state management, outputs, and methods for state updates and navigation.\n *\n * @template Args - The type of arguments used in the application.\n * @template Outputs - The type of block outputs extending `BlockOutputsBase`.\n * @template UiState - The type of the UI state.\n * @template Href - The type of navigation href, defaulting to a string starting with `/`.\n *\n * @param state - Initial state of the application, including args, outputs, UI state, and navigation state.\n * @param platforma - A platform interface for interacting with block states.\n * @param settings - Application settings, such as debug flags.\n *\n * @returns A reactive application object with methods, getters, and state.\n */\nexport function createAppV1<\n Args = unknown,\n Outputs extends BlockOutputsBase = BlockOutputsBase,\n UiState = unknown,\n Href extends `/${string}` = `/${string}`,\n>(\n state: BlockState<Args, Outputs, UiState, Href>,\n platforma: PlatformaV1<Args, Outputs, UiState, Href>,\n settings: AppSettings,\n) {\n type AppModel = {\n args: Args;\n ui: UiState;\n };\n\n const log = (msg: string, ...rest: unknown[]) => {\n if (settings.debug) {\n console.log(`%c>>> %c${msg}`, 'color: orange; font-weight: bold', 'color: orange', ...rest);\n }\n };\n\n /**\n * Reactive snapshot of the application state, including args, outputs, UI state, and navigation state.\n */\n const snapshot = reactive({\n args: Object.freeze(state.args),\n outputs: Object.freeze(state.outputs),\n ui: Object.freeze(state.ui),\n navigationState: Object.freeze(state.navigationState) as NavigationState<Href>,\n }) as {\n args: Readonly<Args>;\n outputs: Partial<Readonly<Outputs>>;\n ui: Readonly<UiState>;\n navigationState: Readonly<NavigationState<Href>>;\n };\n\n const debounceSpan = settings.debounceSpan ?? 200;\n\n const maxWait = tap(settings.debounceMaxWait ?? 0, (v) => v < 20_000 ? 20_000 : v < debounceSpan ? debounceSpan * 100 : v);\n\n const setBlockArgs = useDebounceFn((args: Args) => {\n if (!isJsonEqual(args, snapshot.args)) {\n platforma.setBlockArgs(args);\n }\n }, debounceSpan, { maxWait });\n\n const setBlockUiState = useDebounceFn((ui: UiState) => {\n if (!isJsonEqual(ui, snapshot.ui)) {\n platforma.setBlockUiState(ui);\n }\n }, debounceSpan, { maxWait });\n\n const setBlockArgsAndUiState = useDebounceFn((args: Args, ui: UiState) => {\n if (!isJsonEqual(args, snapshot.args) || !isJsonEqual(ui, snapshot.ui)) {\n platforma.setBlockArgsAndUiState(args, ui);\n }\n }, debounceSpan, { maxWait });\n\n (platforma as unknown as PlatformaV1<Args, Outputs, UiState, Href>).onStateUpdates(async (updates) => {\n updates.forEach((patch) => {\n if (patch.key === 'args' && !isJsonEqual(snapshot.args, patch.value)) {\n snapshot.args = Object.freeze(patch.value);\n log('args patch', snapshot.args);\n }\n\n if (patch.key === 'ui' && !isJsonEqual(snapshot.ui, patch.value)) {\n snapshot.ui = Object.freeze(patch.value);\n log('ui patch', snapshot.ui);\n }\n\n if (patch.key === 'outputs' && !isJsonEqual(snapshot.outputs, patch.value)) {\n snapshot.outputs = Object.freeze(patch.value);\n log('outputs patch', snapshot.outputs);\n }\n\n if (patch.key === 'navigationState' && !isJsonEqual(snapshot.navigationState, patch.value)) {\n snapshot.navigationState = Object.freeze(patch.value);\n log('navigationState patch', snapshot.navigationState);\n }\n });\n\n await nextTick();\n });\n\n const cloneArgs = () => deepClone(snapshot.args) as Args;\n const cloneUiState = () => deepClone(snapshot.ui) as UiState;\n const cloneNavigationState = () => deepClone(snapshot.navigationState) as Mutable<NavigationState<Href>>;\n\n const methods = {\n createArgsModel<T = Args>(options: StateModelOptions<Args, T> = {}) {\n return createModel<T, Args>({\n get() {\n if (options.transform) {\n return options.transform(snapshot.args);\n }\n\n return snapshot.args as T;\n },\n validate: options.validate,\n autoSave: true,\n onSave(newArgs) {\n setBlockArgs(newArgs);\n },\n });\n },\n /**\n * defaultUiState is temporarily here, remove it after implementing initialUiState\n */\n createUiModel<T = UiState>(options: StateModelOptions<UiState, T> = {}, defaultUiState: () => UiState) {\n return createModel<T, UiState>({\n get() {\n if (options.transform) {\n return options.transform(snapshot.ui);\n }\n\n return (snapshot.ui ?? defaultUiState()) as T;\n },\n validate: options.validate,\n autoSave: true,\n onSave(newData) {\n setBlockUiState(newData);\n },\n });\n },\n /**\n * Note: Don't forget to list the output names, like: useOutputs('output1', 'output2', ...etc)\n * @param keys - List of output names\n * @returns {OptionalResult<UnwrapOutputs<Outputs, K>>}\n */\n useOutputs<K extends keyof Outputs>(...keys: K[]): OptionalResult<UnwrapOutputs<Outputs, K>> {\n const data = reactive({\n errors: undefined,\n value: undefined,\n });\n\n watch(\n () => snapshot.outputs,\n () => {\n try {\n Object.assign(data, {\n value: this.unwrapOutputs<K>(...keys),\n errors: undefined,\n });\n } catch (error) {\n Object.assign(data, {\n value: undefined,\n errors: [String(error)],\n });\n }\n },\n { immediate: true, deep: true },\n );\n\n return data as OptionalResult<UnwrapOutputs<Outputs, K>>;\n },\n /**\n * Retrieves the unwrapped values of outputs for the given keys.\n *\n * @template K - Keys of the outputs to unwrap.\n * @param keys - List of output names.\n * @throws Error if the outputs contain errors.\n * @returns An object with unwrapped output values.\n */\n unwrapOutputs<K extends keyof Outputs>(...keys: K[]): UnwrapOutputs<Outputs, K> {\n const outputs = snapshot.outputs;\n const entries = keys.map((key) => [key, unwrapValueOrErrors(outputs[key])]);\n return Object.fromEntries(entries);\n },\n /**\n * Updates the arguments state by applying a callback.\n *\n * @param cb - Callback to modify the current arguments.\n * @returns A promise resolving after the update is applied.\n */\n updateArgs(cb: (args: Args) => void) {\n const newArgs = cloneArgs();\n cb(newArgs);\n return platforma.setBlockArgs(newArgs);\n },\n /**\n * Updates the UI state by applying a callback.\n *\n * @param cb - Callback to modify the current UI state.\n * @returns A promise resolving after the update is applied.\n * @todo Make it mutable since there is already an initial one\n */\n updateUiState(cb: (args: UiState) => UiState): Promise<void> {\n const newUiState = cloneUiState();\n return platforma.setBlockUiState(cb(newUiState));\n },\n /**\n * Updates the navigation state by applying a callback.\n *\n * @param cb - Callback to modify the current navigation state.\n * @returns A promise resolving after the update is applied.\n */\n updateNavigationState(cb: (args: Mutable<NavigationState<Href>>) => void) {\n const newState = cloneNavigationState();\n cb(newState);\n return platforma.setNavigationState(newState);\n },\n /**\n * Navigates to a specific href by updating the navigation state.\n *\n * @param href - The target href to navigate to.\n * @returns A promise resolving after the navigation state is updated.\n */\n navigateTo(href: Href) {\n const newState = cloneNavigationState();\n newState.href = href;\n return platforma.setNavigationState(newState);\n },\n };\n\n const outputs = computed<OutputValues<Outputs>>(() => {\n const entries = Object.entries(snapshot.outputs).map(([k, vOrErr]) => [k, vOrErr.ok && vOrErr.value !== undefined ? vOrErr.value : undefined]);\n return Object.fromEntries(entries);\n });\n\n const outputErrors = computed<OutputErrors<Outputs>>(() => {\n const entries = Object.entries(snapshot.outputs).map(([k, vOrErr]) => [k, vOrErr && vOrErr.ok === false ? new MultiError(vOrErr.errors) : undefined]);\n return Object.fromEntries(entries);\n });\n\n const getters = {\n snapshot,\n queryParams: computed(() => parseQuery<Href>(snapshot.navigationState.href)),\n href: computed(() => snapshot.navigationState.href),\n hasErrors: computed(() => Object.values(snapshot.outputs).some((v) => !v?.ok)),\n };\n\n const model = createAppModel(\n {\n get() {\n return { args: snapshot.args, ui: snapshot.ui } as AppModel;\n },\n autoSave: true,\n onSave(newData: AppModel) {\n setBlockArgsAndUiState(newData.args, newData.ui);\n },\n },\n {\n outputs,\n outputErrors,\n },\n settings,\n );\n\n return reactive(Object.assign(model, methods, getters));\n}\n\nexport type BaseAppV1<\n Args = unknown,\n Outputs extends BlockOutputsBase = BlockOutputsBase,\n UiState = unknown,\n Href extends `/${string}` = `/${string}`,\n> = ReturnType<typeof createAppV1<Args, Outputs, UiState, Href>>;\n"],"names":["createAppV1","state","platforma","settings","log","msg","rest","snapshot","reactive","debounceSpan","maxWait","tap","v","setBlockArgs","useDebounceFn","args","isJsonEqual","setBlockUiState","ui","setBlockArgsAndUiState","updates","patch","nextTick","cloneArgs","deepClone","cloneUiState","cloneNavigationState","methods","options","createModel","newArgs","defaultUiState","newData","keys","data","watch","error","outputs","entries","key","unwrapValueOrErrors","cb","newUiState","newState","href","computed","k","vOrErr","outputErrors","MultiError","getters","parseQuery","model","createAppModel"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Mutable } from '@milaboratories/helpers';
|
|
2
2
|
import { NavigationState, BlockOutputsBase, BlockState, PlatformaV2, ValueWithUTag, AuthorMarker } from '@platforma-sdk/model';
|
|
3
3
|
import { StateModelOptions, UnwrapOutputs, OutputValues, OutputErrors, AppSettings } from '../types';
|
|
4
|
-
export declare const patchPoolingDelay =
|
|
4
|
+
export declare const patchPoolingDelay = 150;
|
|
5
5
|
export declare const createNextAuthorMarker: (marker: AuthorMarker | undefined) => AuthorMarker;
|
|
6
6
|
/**
|
|
7
7
|
* Creates an application instance with reactive state management, outputs, and methods for state updates and navigation.
|
|
@@ -1,60 +1,60 @@
|
|
|
1
1
|
import { delay as L } from "../lib/util/helpers/dist/utils.js";
|
|
2
|
-
import { uniqueId as
|
|
3
|
-
import { deepClone as
|
|
2
|
+
import { uniqueId as R } from "../lib/util/helpers/dist/strings.js";
|
|
3
|
+
import { deepClone as i } from "../lib/util/helpers/dist/objects.js";
|
|
4
4
|
import "../lib/util/helpers/dist/test_timeouts.js";
|
|
5
5
|
import { unwrapResult as c, hasAbortError as G } from "@platforma-sdk/model";
|
|
6
|
-
import { ref as
|
|
7
|
-
import { createModel as
|
|
6
|
+
import { ref as A, computed as d, reactive as N } from "vue";
|
|
7
|
+
import { createModel as O } from "../createModel.js";
|
|
8
8
|
import { parseQuery as H } from "../urls.js";
|
|
9
9
|
import { MultiError as K, unwrapValueOrErrors as W } from "../utils.js";
|
|
10
10
|
import "../node_modules/.pnpm/fast-json-patch@3.1.1/node_modules/fast-json-patch/index.js";
|
|
11
11
|
import { UpdateSerializer as v } from "./UpdateSerializer.js";
|
|
12
12
|
import { watchIgnorable as X } from "@vueuse/core";
|
|
13
|
-
import { applyPatch as
|
|
14
|
-
const
|
|
15
|
-
authorId: (n == null ? void 0 : n.authorId) ??
|
|
13
|
+
import { applyPatch as Q } from "../node_modules/.pnpm/fast-json-patch@3.1.1/node_modules/fast-json-patch/module/core.js";
|
|
14
|
+
const V = 150, Y = (n) => ({
|
|
15
|
+
authorId: (n == null ? void 0 : n.authorId) ?? R(),
|
|
16
16
|
localVersion: ((n == null ? void 0 : n.localVersion) ?? 0) + 1
|
|
17
|
-
}),
|
|
17
|
+
}), _ = (n) => {
|
|
18
18
|
try {
|
|
19
19
|
return JSON.stringify(n, null, 2);
|
|
20
20
|
} catch (u) {
|
|
21
21
|
return u instanceof Error ? u.message : String(u);
|
|
22
22
|
}
|
|
23
23
|
};
|
|
24
|
-
function de(n, u,
|
|
25
|
-
const
|
|
26
|
-
|
|
24
|
+
function de(n, u, m) {
|
|
25
|
+
const r = (e, ...t) => {
|
|
26
|
+
m.debug && console.log(`%c>>> %c${e}`, "color: orange; font-weight: bold", "color: orange", ...t.map((o) => _(o)));
|
|
27
27
|
}, b = (e, ...t) => {
|
|
28
|
-
console.error(`%c>>> %c${e}`, "color: red; font-weight: bold", "color: red", ...t.map((o) =>
|
|
28
|
+
console.error(`%c>>> %c${e}`, "color: red; font-weight: bold", "color: red", ...t.map((o) => _(o)));
|
|
29
29
|
}, s = {
|
|
30
30
|
isExternalSnapshot: !1,
|
|
31
31
|
author: {
|
|
32
|
-
authorId:
|
|
32
|
+
authorId: R(),
|
|
33
33
|
localVersion: 0
|
|
34
34
|
}
|
|
35
|
-
},
|
|
36
|
-
const e = Object.entries(
|
|
35
|
+
}, f = () => (s.author = Y(s.author), r("nextAuthorMarker", s.author), s.author), g = A(!1), S = A(n.uTag), h = m.debounceSpan ?? 200, y = new v({ debounceSpan: h }), U = new v({ debounceSpan: h }), M = new v({ debounceSpan: h }), k = new v({ debounceSpan: h }), a = A(n.value), T = async (e) => u.setBlockArgs(e, f()), E = async (e) => u.setBlockUiState(e, f()), D = async (e, t) => u.setBlockArgsAndUiState(e, t, f()), q = async (e) => u.setNavigationState(e), C = d(() => {
|
|
36
|
+
const e = Object.entries(a.value.outputs).map(([t, o]) => [t, o.ok && o.value !== void 0 ? o.value : void 0]);
|
|
37
37
|
return Object.fromEntries(e);
|
|
38
|
-
}),
|
|
39
|
-
const e = Object.entries(
|
|
38
|
+
}), $ = d(() => {
|
|
39
|
+
const e = Object.entries(a.value.outputs).map(([t, o]) => [t, o && o.ok === !1 ? new K(o.errors) : void 0]);
|
|
40
40
|
return Object.fromEntries(e);
|
|
41
|
-
}),
|
|
41
|
+
}), l = N({
|
|
42
42
|
error: "",
|
|
43
43
|
model: {
|
|
44
|
-
args:
|
|
45
|
-
ui:
|
|
46
|
-
outputs:
|
|
47
|
-
outputErrors:
|
|
44
|
+
args: i(a.value.args),
|
|
45
|
+
ui: i(a.value.ui),
|
|
46
|
+
outputs: C,
|
|
47
|
+
outputErrors: $
|
|
48
48
|
}
|
|
49
|
-
}), { ignoreUpdates:
|
|
50
|
-
() =>
|
|
49
|
+
}), { ignoreUpdates: x } = X(
|
|
50
|
+
() => l.model,
|
|
51
51
|
(e) => {
|
|
52
|
-
const t =
|
|
53
|
-
|
|
52
|
+
const t = i(e);
|
|
53
|
+
r("setArgsAndUiStateQueue appModel.model, args", t.args, "ui", t.ui), M.run(() => D(t.args, t.ui).then(c));
|
|
54
54
|
},
|
|
55
55
|
{ deep: !0 }
|
|
56
56
|
), z = (e) => {
|
|
57
|
-
|
|
57
|
+
r("updateAppModel", e), l.model.args = i(e.args), l.model.ui = i(e.ui);
|
|
58
58
|
};
|
|
59
59
|
(async () => {
|
|
60
60
|
var e, t;
|
|
@@ -64,27 +64,29 @@ function de(n, u, A) {
|
|
|
64
64
|
});
|
|
65
65
|
}); !g.value; )
|
|
66
66
|
try {
|
|
67
|
-
const o = await u.getPatches(
|
|
68
|
-
if (
|
|
69
|
-
await new Promise((
|
|
67
|
+
const o = await u.getPatches(S.value).then(c);
|
|
68
|
+
if (r("patches.length", o.value.length), r("uTagRef.value", S.value), r("patches.uTag", o.uTag), r("patches.author", o.author), r("data.author", s.author), S.value = o.uTag, o.value.length === 0) {
|
|
69
|
+
await new Promise((w) => setTimeout(w, V));
|
|
70
70
|
continue;
|
|
71
71
|
}
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
})) : r
|
|
72
|
+
const p = ((e = s.author) == null ? void 0 : e.authorId) !== ((t = o.author) == null ? void 0 : t.authorId);
|
|
73
|
+
p || s.isExternalSnapshot ? (r("got external changes, applying them to the snapshot", o.value), x(() => {
|
|
74
|
+
a.value = Q(a.value, o.value, !1, !1).newDocument, z({ args: a.value.args, ui: a.value.ui }), s.isExternalSnapshot = p;
|
|
75
|
+
})) : (r("outputs changed", o.value), x(() => {
|
|
76
|
+
a.value = Q(a.value, o.value).newDocument;
|
|
77
|
+
})), await new Promise((w) => setTimeout(w, V));
|
|
76
78
|
} catch (o) {
|
|
77
|
-
G(o) ? (
|
|
79
|
+
G(o) ? (r("patches loop aborted"), g.value = !0) : (b("error in patches loop", o), await new Promise((p) => setTimeout(p, 1e3)));
|
|
78
80
|
}
|
|
79
81
|
})();
|
|
80
|
-
const
|
|
81
|
-
cloneArgs:
|
|
82
|
-
cloneUiState:
|
|
83
|
-
cloneNavigationState:
|
|
82
|
+
const j = () => i(l.model.args), I = () => i(l.model.ui), P = () => i(a.value.navigationState), F = {
|
|
83
|
+
cloneArgs: j,
|
|
84
|
+
cloneUiState: I,
|
|
85
|
+
cloneNavigationState: P,
|
|
84
86
|
createArgsModel(e = {}) {
|
|
85
|
-
return
|
|
87
|
+
return O({
|
|
86
88
|
get() {
|
|
87
|
-
return e.transform ? e.transform(
|
|
89
|
+
return e.transform ? e.transform(a.value.args) : a.value.args;
|
|
88
90
|
},
|
|
89
91
|
validate: e.validate,
|
|
90
92
|
autoSave: !0,
|
|
@@ -97,9 +99,9 @@ function de(n, u, A) {
|
|
|
97
99
|
* defaultUiState is temporarily here, remove it after implementing initialUiState
|
|
98
100
|
*/
|
|
99
101
|
createUiModel(e = {}, t) {
|
|
100
|
-
return
|
|
102
|
+
return O({
|
|
101
103
|
get() {
|
|
102
|
-
return e.transform ? e.transform(
|
|
104
|
+
return e.transform ? e.transform(a.value.ui) : a.value.ui ?? t();
|
|
103
105
|
},
|
|
104
106
|
validate: e.validate,
|
|
105
107
|
autoSave: !0,
|
|
@@ -117,7 +119,7 @@ function de(n, u, A) {
|
|
|
117
119
|
* @returns An object with unwrapped output values.
|
|
118
120
|
*/
|
|
119
121
|
unwrapOutputs(...e) {
|
|
120
|
-
const t =
|
|
122
|
+
const t = a.value.outputs, o = e.map((p) => [p, W(t[p])]);
|
|
121
123
|
return Object.fromEntries(o);
|
|
122
124
|
},
|
|
123
125
|
/**
|
|
@@ -127,8 +129,8 @@ function de(n, u, A) {
|
|
|
127
129
|
* @returns A promise resolving after the update is applied.
|
|
128
130
|
*/
|
|
129
131
|
updateArgs(e) {
|
|
130
|
-
const t =
|
|
131
|
-
return e(t),
|
|
132
|
+
const t = j();
|
|
133
|
+
return e(t), r("updateArgs", t), l.model.args = t, y.run(() => T(t).then(c));
|
|
132
134
|
},
|
|
133
135
|
/**
|
|
134
136
|
* Updates the UI state by applying a callback.
|
|
@@ -138,8 +140,8 @@ function de(n, u, A) {
|
|
|
138
140
|
* @todo Make it mutable since there is already an initial one
|
|
139
141
|
*/
|
|
140
142
|
updateUiState(e) {
|
|
141
|
-
const t = e(
|
|
142
|
-
return
|
|
143
|
+
const t = e(I());
|
|
144
|
+
return r("updateUiState", t), l.model.ui = t, U.run(() => E(t).then(c));
|
|
143
145
|
},
|
|
144
146
|
/**
|
|
145
147
|
* Navigates to a specific href by updating the navigation state.
|
|
@@ -148,24 +150,24 @@ function de(n, u, A) {
|
|
|
148
150
|
* @returns A promise resolving after the navigation state is updated.
|
|
149
151
|
*/
|
|
150
152
|
navigateTo(e) {
|
|
151
|
-
const t =
|
|
152
|
-
return t.href = e,
|
|
153
|
+
const t = P();
|
|
154
|
+
return t.href = e, k.run(() => q(t).then(c));
|
|
153
155
|
},
|
|
154
156
|
async allSettled() {
|
|
155
157
|
return await L(0), M.allSettled();
|
|
156
158
|
}
|
|
157
159
|
}, J = {
|
|
158
160
|
closedRef: g,
|
|
159
|
-
snapshot:
|
|
160
|
-
queryParams:
|
|
161
|
-
href:
|
|
162
|
-
hasErrors:
|
|
163
|
-
};
|
|
164
|
-
return
|
|
161
|
+
snapshot: a,
|
|
162
|
+
queryParams: d(() => H(a.value.navigationState.href)),
|
|
163
|
+
href: d(() => a.value.navigationState.href),
|
|
164
|
+
hasErrors: d(() => Object.values(a.value.outputs).some((e) => !(e != null && e.ok)))
|
|
165
|
+
}, B = N(Object.assign(l, F, J));
|
|
166
|
+
return m.debug && (globalThis.__block_app__ = B), B;
|
|
165
167
|
}
|
|
166
168
|
export {
|
|
167
169
|
de as createAppV2,
|
|
168
170
|
Y as createNextAuthorMarker,
|
|
169
|
-
|
|
171
|
+
V as patchPoolingDelay
|
|
170
172
|
};
|
|
171
173
|
//# sourceMappingURL=createAppV2.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createAppV2.js","sources":["../../src/internal/createAppV2.ts"],"sourcesContent":["import { deepClone, delay, uniqueId } from '@milaboratories/helpers';\nimport type { Mutable } from '@milaboratories/helpers';\nimport type { NavigationState, BlockOutputsBase, BlockState, PlatformaV2, ValueWithUTag, AuthorMarker } from '@platforma-sdk/model';\nimport { hasAbortError, unwrapResult } from '@platforma-sdk/model';\nimport type { Ref } from 'vue';\nimport { reactive, computed, ref } from 'vue';\nimport type { StateModelOptions, UnwrapOutputs, OutputValues, OutputErrors, AppSettings } from '../types';\nimport { createModel } from '../createModel';\nimport { parseQuery } from '../urls';\nimport { MultiError, unwrapValueOrErrors } from '../utils';\nimport { applyPatch } from 'fast-json-patch';\nimport { UpdateSerializer } from './UpdateSerializer';\nimport { watchIgnorable } from '@vueuse/core';\n\nexport const patchPoolingDelay = 100;\n\nexport const createNextAuthorMarker = (marker: AuthorMarker | undefined): AuthorMarker => ({\n authorId: marker?.authorId ?? uniqueId(),\n localVersion: (marker?.localVersion ?? 0) + 1,\n});\n\nconst stringifyForDebug = (v: unknown) => {\n try {\n return JSON.stringify(v, null, 2);\n } catch (err) {\n return err instanceof Error ? err.message : String(err);\n }\n};\n\n/**\n * Creates an application instance with reactive state management, outputs, and methods for state updates and navigation.\n *\n * @template Args - The type of arguments used in the application.\n * @template Outputs - The type of block outputs extending `BlockOutputsBase`.\n * @template UiState - The type of the UI state.\n * @template Href - The type of navigation href, defaulting to a string starting with `/`.\n *\n * @param state - Initial state of the application, including args, outputs, UI state, and navigation state.\n * @param platforma - A platform interface for interacting with block states.\n * @param settings - Application settings, such as debug flags.\n *\n * @returns A reactive application object with methods, getters, and state.\n */\nexport function createAppV2<\n Args = unknown,\n Outputs extends BlockOutputsBase = BlockOutputsBase,\n UiState = unknown,\n Href extends `/${string}` = `/${string}`,\n>(\n state: ValueWithUTag<BlockState<Args, Outputs, UiState, Href>>,\n platforma: PlatformaV2<Args, Outputs, UiState, Href>,\n settings: AppSettings,\n) {\n const debug = (msg: string, ...rest: unknown[]) => {\n if (settings.debug) {\n console.log(`%c>>> %c${msg}`, 'color: orange; font-weight: bold', 'color: orange', ...rest.map((r) => stringifyForDebug(r)));\n }\n };\n\n const error = (msg: string, ...rest: unknown[]) => {\n console.error(`%c>>> %c${msg}`, 'color: red; font-weight: bold', 'color: red', ...rest.map((r) => stringifyForDebug(r)));\n };\n\n const data = {\n isExternalSnapshot: false,\n author: {\n authorId: uniqueId(),\n localVersion: 0,\n },\n };\n\n const nextAuthorMarker = () => {\n data.author = createNextAuthorMarker(data.author);\n debug('nextAuthorMarker', data.author);\n return data.author;\n };\n\n const closedRef = ref(false);\n\n const uTagRef = ref(state.uTag);\n\n const debounceSpan = settings.debounceSpan ?? 200;\n\n const setArgsQueue = new UpdateSerializer({ debounceSpan });\n const setUiStateQueue = new UpdateSerializer({ debounceSpan });\n const setArgsAndUiStateQueue = new UpdateSerializer({ debounceSpan });\n const setNavigationStateQueue = new UpdateSerializer({ debounceSpan });\n /**\n * Reactive snapshot of the application state, including args, outputs, UI state, and navigation state.\n */\n const snapshot = ref<{\n args: Args;\n outputs: Partial<Outputs>;\n ui: UiState;\n navigationState: NavigationState<Href>;\n }>(state.value) as Ref<{\n args: Args;\n outputs: Partial<Outputs>;\n ui: UiState;\n navigationState: NavigationState<Href>;\n }>;\n\n const setBlockArgs = async (args: Args) => {\n return platforma.setBlockArgs(args, nextAuthorMarker());\n };\n\n const setBlockUiState = async (ui: UiState) => {\n return platforma.setBlockUiState(ui, nextAuthorMarker());\n };\n\n const setBlockArgsAndUiState = async (args: Args, ui: UiState) => {\n return platforma.setBlockArgsAndUiState(args, ui, nextAuthorMarker());\n };\n\n const setNavigationState = async (state: NavigationState<Href>) => {\n return platforma.setNavigationState(state);\n };\n\n const outputs = computed<OutputValues<Outputs>>(() => {\n const entries = Object.entries(snapshot.value.outputs as Partial<Readonly<Outputs>>).map(([k, vOrErr]) => [k, vOrErr.ok && vOrErr.value !== undefined ? vOrErr.value : undefined]);\n return Object.fromEntries(entries);\n });\n\n const outputErrors = computed<OutputErrors<Outputs>>(() => {\n const entries = Object.entries(snapshot.value.outputs as Partial<Readonly<Outputs>>).map(([k, vOrErr]) => [k, vOrErr && !vOrErr.ok ? new MultiError(vOrErr.errors) : undefined]);\n return Object.fromEntries(entries);\n });\n\n const appModel = reactive({\n error: '',\n model: {\n args: deepClone(snapshot.value.args) as Args,\n ui: deepClone(snapshot.value.ui) as UiState,\n outputs,\n outputErrors,\n },\n }) as {\n error: string;\n model: {\n args: Args;\n ui: UiState;\n outputs: OutputValues<Outputs>;\n outputErrors: OutputErrors<Outputs>;\n };\n };\n\n const { ignoreUpdates } = watchIgnorable(\n () => appModel.model,\n (_newData) => {\n const newData = deepClone(_newData);\n debug('setArgsAndUiStateQueue appModel.model', newData);\n setArgsAndUiStateQueue.run(() => setBlockArgsAndUiState(newData.args, newData.ui).then(unwrapResult));\n },\n { deep: true },\n );\n\n const updateAppModel = (newData: {\n args: Args;\n ui: UiState;\n }) => {\n debug('updateAppModel', newData);\n appModel.model.args = deepClone(newData.args) as Args;\n appModel.model.ui = deepClone(newData.ui) as UiState;\n };\n\n (async () => {\n window.addEventListener('beforeunload', () => {\n closedRef.value = true;\n platforma.dispose().then(unwrapResult).catch((err) => {\n error('error in dispose', err);\n });\n });\n\n while (!closedRef.value) {\n try {\n const patches = await platforma.getPatches(uTagRef.value).then(unwrapResult);\n\n debug('patches.length', patches.value.length);\n debug('uTagRef.value', uTagRef.value);\n debug('patches.uTag', patches.uTag);\n debug('patches.author', patches.author);\n debug('data.author', data.author);\n\n uTagRef.value = patches.uTag;\n\n if (patches.value.length === 0) {\n await new Promise((resolve) => setTimeout(resolve, patchPoolingDelay));\n continue;\n }\n\n const isAuthorChanged = data.author?.authorId !== patches.author?.authorId;\n\n // Immutable behavior, apply external changes to the snapshot\n if (isAuthorChanged || data.isExternalSnapshot) {\n debug('got external changes, applying them to the snapshot', snapshot.value);\n ignoreUpdates(() => {\n snapshot.value = applyPatch(snapshot.value, patches.value, false, false).newDocument;\n updateAppModel({ args: snapshot.value.args, ui: snapshot.value.ui });\n data.isExternalSnapshot = isAuthorChanged;\n });\n } else {\n // Mutable behavior\n snapshot.value = applyPatch(snapshot.value, patches.value).newDocument;\n }\n\n await new Promise((resolve) => setTimeout(resolve, patchPoolingDelay));\n } catch (err) {\n if (hasAbortError(err)) {\n debug('patches loop aborted');\n closedRef.value = true;\n } else {\n error('error in patches loop', err);\n await new Promise((resolve) => setTimeout(resolve, 1000));\n }\n }\n }\n })();\n\n const cloneArgs = () => deepClone(appModel.model.args) as Args;\n const cloneUiState = () => deepClone(appModel.model.ui) as UiState;\n const cloneNavigationState = () => deepClone(snapshot.value.navigationState) as Mutable<NavigationState<Href>>;\n\n const methods = {\n cloneArgs,\n cloneUiState,\n cloneNavigationState,\n createArgsModel<T extends Args = Args>(options: StateModelOptions<Args, T> = {}) {\n return createModel<T, Args>({\n get() {\n if (options.transform) {\n return options.transform(snapshot.value.args as Args);\n }\n\n return snapshot.value.args as T;\n },\n validate: options.validate,\n autoSave: true,\n onSave(newArgs) {\n setArgsQueue.run(() => setBlockArgs(newArgs).then(unwrapResult));\n },\n });\n },\n /**\n * defaultUiState is temporarily here, remove it after implementing initialUiState\n */\n createUiModel<T extends UiState = UiState>(options: StateModelOptions<UiState, T> = {}, defaultUiState: () => UiState) {\n return createModel<T, UiState>({\n get() {\n if (options.transform) {\n return options.transform(snapshot.value.ui as UiState);\n }\n\n return (snapshot.value.ui ?? defaultUiState()) as T;\n },\n validate: options.validate,\n autoSave: true,\n onSave(newData) {\n setUiStateQueue.run(() => setBlockUiState(newData).then(unwrapResult));\n },\n });\n },\n /**\n * Retrieves the unwrapped values of outputs for the given keys.\n *\n * @template K - Keys of the outputs to unwrap.\n * @param keys - List of output names.\n * @throws Error if the outputs contain errors.\n * @returns An object with unwrapped output values.\n */\n unwrapOutputs<K extends keyof Outputs>(...keys: K[]): UnwrapOutputs<Outputs, K> {\n const outputs = snapshot.value.outputs as Partial<Readonly<Outputs>>;\n const entries = keys.map((key) => [key, unwrapValueOrErrors(outputs[key])]);\n return Object.fromEntries(entries);\n },\n /**\n * Updates the arguments state by applying a callback.\n *\n * @param cb - Callback to modify the current arguments.\n * @returns A promise resolving after the update is applied.\n */\n updateArgs(cb: (args: Args) => void): Promise<boolean> {\n const newArgs = cloneArgs();\n cb(newArgs);\n debug('updateArgs', newArgs);\n appModel.model.args = newArgs;\n return setArgsQueue.run(() => setBlockArgs(newArgs).then(unwrapResult));\n },\n /**\n * Updates the UI state by applying a callback.\n *\n * @param cb - Callback to modify the current UI state.\n * @returns A promise resolving after the update is applied.\n * @todo Make it mutable since there is already an initial one\n */\n updateUiState(cb: (args: UiState) => UiState): Promise<boolean> {\n const newUiState = cb(cloneUiState());\n debug('updateUiState', newUiState);\n appModel.model.ui = newUiState;\n return setUiStateQueue.run(() => setBlockUiState(newUiState).then(unwrapResult));\n },\n /**\n * Navigates to a specific href by updating the navigation state.\n *\n * @param href - The target href to navigate to.\n * @returns A promise resolving after the navigation state is updated.\n */\n navigateTo(href: Href) {\n const newState = cloneNavigationState();\n newState.href = href;\n return setNavigationStateQueue.run(() => setNavigationState(newState).then(unwrapResult));\n },\n async allSettled() {\n await delay(0);\n return setArgsAndUiStateQueue.allSettled();\n },\n };\n\n const getters = {\n closedRef,\n snapshot,\n queryParams: computed(() => parseQuery<Href>(snapshot.value.navigationState.href as Href)),\n href: computed(() => snapshot.value.navigationState.href),\n hasErrors: computed(() => Object.values(snapshot.value.outputs as Partial<Readonly<Outputs>>).some((v) => !v?.ok)),\n };\n\n return reactive(Object.assign(appModel, methods, getters));\n}\n\nexport type BaseAppV2<\n Args = unknown,\n Outputs extends BlockOutputsBase = BlockOutputsBase,\n UiState = unknown,\n Href extends `/${string}` = `/${string}`,\n> = ReturnType<typeof createAppV2<Args, Outputs, UiState, Href>>;\n"],"names":["patchPoolingDelay","createNextAuthorMarker","marker","uniqueId","stringifyForDebug","v","err","createAppV2","state","platforma","settings","debug","msg","rest","r","error","data","nextAuthorMarker","closedRef","ref","uTagRef","debounceSpan","setArgsQueue","UpdateSerializer","setUiStateQueue","setArgsAndUiStateQueue","setNavigationStateQueue","snapshot","setBlockArgs","args","setBlockUiState","ui","setBlockArgsAndUiState","setNavigationState","outputs","computed","entries","k","vOrErr","outputErrors","MultiError","appModel","reactive","deepClone","ignoreUpdates","watchIgnorable","_newData","newData","unwrapResult","updateAppModel","patches","resolve","isAuthorChanged","_a","_b","applyPatch","hasAbortError","cloneArgs","cloneUiState","cloneNavigationState","methods","options","createModel","newArgs","defaultUiState","keys","key","unwrapValueOrErrors","cb","newUiState","href","newState","delay","getters","parseQuery"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"createAppV2.js","sources":["../../src/internal/createAppV2.ts"],"sourcesContent":["import { deepClone, delay, uniqueId } from '@milaboratories/helpers';\nimport type { Mutable } from '@milaboratories/helpers';\nimport type { NavigationState, BlockOutputsBase, BlockState, PlatformaV2, ValueWithUTag, AuthorMarker } from '@platforma-sdk/model';\nimport { hasAbortError, unwrapResult } from '@platforma-sdk/model';\nimport type { Ref } from 'vue';\nimport { reactive, computed, ref } from 'vue';\nimport type { StateModelOptions, UnwrapOutputs, OutputValues, OutputErrors, AppSettings } from '../types';\nimport { createModel } from '../createModel';\nimport { parseQuery } from '../urls';\nimport { MultiError, unwrapValueOrErrors } from '../utils';\nimport { applyPatch } from 'fast-json-patch';\nimport { UpdateSerializer } from './UpdateSerializer';\nimport { watchIgnorable } from '@vueuse/core';\n\nexport const patchPoolingDelay = 150;\n\nexport const createNextAuthorMarker = (marker: AuthorMarker | undefined): AuthorMarker => ({\n authorId: marker?.authorId ?? uniqueId(),\n localVersion: (marker?.localVersion ?? 0) + 1,\n});\n\nconst stringifyForDebug = (v: unknown) => {\n try {\n return JSON.stringify(v, null, 2);\n } catch (err) {\n return err instanceof Error ? err.message : String(err);\n }\n};\n\n/**\n * Creates an application instance with reactive state management, outputs, and methods for state updates and navigation.\n *\n * @template Args - The type of arguments used in the application.\n * @template Outputs - The type of block outputs extending `BlockOutputsBase`.\n * @template UiState - The type of the UI state.\n * @template Href - The type of navigation href, defaulting to a string starting with `/`.\n *\n * @param state - Initial state of the application, including args, outputs, UI state, and navigation state.\n * @param platforma - A platform interface for interacting with block states.\n * @param settings - Application settings, such as debug flags.\n *\n * @returns A reactive application object with methods, getters, and state.\n */\nexport function createAppV2<\n Args = unknown,\n Outputs extends BlockOutputsBase = BlockOutputsBase,\n UiState = unknown,\n Href extends `/${string}` = `/${string}`,\n>(\n state: ValueWithUTag<BlockState<Args, Outputs, UiState, Href>>,\n platforma: PlatformaV2<Args, Outputs, UiState, Href>,\n settings: AppSettings,\n) {\n const debug = (msg: string, ...rest: unknown[]) => {\n if (settings.debug) {\n console.log(`%c>>> %c${msg}`, 'color: orange; font-weight: bold', 'color: orange', ...rest.map((r) => stringifyForDebug(r)));\n }\n };\n\n const error = (msg: string, ...rest: unknown[]) => {\n console.error(`%c>>> %c${msg}`, 'color: red; font-weight: bold', 'color: red', ...rest.map((r) => stringifyForDebug(r)));\n };\n\n const data = {\n isExternalSnapshot: false,\n author: {\n authorId: uniqueId(),\n localVersion: 0,\n },\n };\n\n const nextAuthorMarker = () => {\n data.author = createNextAuthorMarker(data.author);\n debug('nextAuthorMarker', data.author);\n return data.author;\n };\n\n const closedRef = ref(false);\n\n const uTagRef = ref(state.uTag);\n\n const debounceSpan = settings.debounceSpan ?? 200;\n\n const setArgsQueue = new UpdateSerializer({ debounceSpan });\n const setUiStateQueue = new UpdateSerializer({ debounceSpan });\n const setArgsAndUiStateQueue = new UpdateSerializer({ debounceSpan });\n const setNavigationStateQueue = new UpdateSerializer({ debounceSpan });\n /**\n * Reactive snapshot of the application state, including args, outputs, UI state, and navigation state.\n */\n const snapshot = ref<{\n args: Args;\n outputs: Partial<Outputs>;\n ui: UiState;\n navigationState: NavigationState<Href>;\n }>(state.value) as Ref<{\n args: Args;\n outputs: Partial<Outputs>;\n ui: UiState;\n navigationState: NavigationState<Href>;\n }>;\n\n const setBlockArgs = async (args: Args) => {\n return platforma.setBlockArgs(args, nextAuthorMarker());\n };\n\n const setBlockUiState = async (ui: UiState) => {\n return platforma.setBlockUiState(ui, nextAuthorMarker());\n };\n\n const setBlockArgsAndUiState = async (args: Args, ui: UiState) => {\n return platforma.setBlockArgsAndUiState(args, ui, nextAuthorMarker());\n };\n\n const setNavigationState = async (state: NavigationState<Href>) => {\n return platforma.setNavigationState(state);\n };\n\n const outputs = computed<OutputValues<Outputs>>(() => {\n const entries = Object.entries(snapshot.value.outputs as Partial<Readonly<Outputs>>).map(([k, vOrErr]) => [k, vOrErr.ok && vOrErr.value !== undefined ? vOrErr.value : undefined]);\n return Object.fromEntries(entries);\n });\n\n const outputErrors = computed<OutputErrors<Outputs>>(() => {\n const entries = Object.entries(snapshot.value.outputs as Partial<Readonly<Outputs>>).map(([k, vOrErr]) => [k, vOrErr && vOrErr.ok === false ? new MultiError(vOrErr.errors) : undefined]);\n return Object.fromEntries(entries);\n });\n\n const appModel = reactive({\n error: '',\n model: {\n args: deepClone(snapshot.value.args) as Args,\n ui: deepClone(snapshot.value.ui) as UiState,\n outputs,\n outputErrors,\n },\n }) as {\n error: string;\n model: {\n args: Args;\n ui: UiState;\n outputs: OutputValues<Outputs>;\n outputErrors: OutputErrors<Outputs>;\n };\n };\n\n const { ignoreUpdates } = watchIgnorable(\n () => appModel.model,\n (_newData) => {\n const newData = deepClone(_newData);\n debug('setArgsAndUiStateQueue appModel.model, args', newData.args, 'ui', newData.ui);\n setArgsAndUiStateQueue.run(() => setBlockArgsAndUiState(newData.args, newData.ui).then(unwrapResult));\n },\n { deep: true },\n );\n\n const updateAppModel = (newData: {\n args: Args;\n ui: UiState;\n }) => {\n debug('updateAppModel', newData);\n appModel.model.args = deepClone(newData.args) as Args;\n appModel.model.ui = deepClone(newData.ui) as UiState;\n };\n\n (async () => {\n window.addEventListener('beforeunload', () => {\n closedRef.value = true;\n platforma.dispose().then(unwrapResult).catch((err) => {\n error('error in dispose', err);\n });\n });\n\n while (!closedRef.value) {\n try {\n const patches = await platforma.getPatches(uTagRef.value).then(unwrapResult);\n\n debug('patches.length', patches.value.length);\n debug('uTagRef.value', uTagRef.value);\n debug('patches.uTag', patches.uTag);\n debug('patches.author', patches.author);\n debug('data.author', data.author);\n\n uTagRef.value = patches.uTag;\n\n if (patches.value.length === 0) {\n await new Promise((resolve) => setTimeout(resolve, patchPoolingDelay));\n continue;\n }\n\n const isAuthorChanged = data.author?.authorId !== patches.author?.authorId;\n\n // Immutable behavior, apply external changes to the snapshot\n if (isAuthorChanged || data.isExternalSnapshot) {\n debug('got external changes, applying them to the snapshot', patches.value);\n ignoreUpdates(() => {\n snapshot.value = applyPatch(snapshot.value, patches.value, false, false).newDocument;\n updateAppModel({ args: snapshot.value.args, ui: snapshot.value.ui });\n data.isExternalSnapshot = isAuthorChanged;\n });\n } else {\n // Mutable behavior\n debug('outputs changed', patches.value);\n ignoreUpdates(() => {\n snapshot.value = applyPatch(snapshot.value, patches.value).newDocument;\n });\n }\n\n await new Promise((resolve) => setTimeout(resolve, patchPoolingDelay));\n } catch (err) {\n if (hasAbortError(err)) {\n debug('patches loop aborted');\n closedRef.value = true;\n } else {\n error('error in patches loop', err);\n await new Promise((resolve) => setTimeout(resolve, 1000));\n }\n }\n }\n })();\n\n const cloneArgs = () => deepClone(appModel.model.args) as Args;\n const cloneUiState = () => deepClone(appModel.model.ui) as UiState;\n const cloneNavigationState = () => deepClone(snapshot.value.navigationState) as Mutable<NavigationState<Href>>;\n\n const methods = {\n cloneArgs,\n cloneUiState,\n cloneNavigationState,\n createArgsModel<T extends Args = Args>(options: StateModelOptions<Args, T> = {}) {\n return createModel<T, Args>({\n get() {\n if (options.transform) {\n return options.transform(snapshot.value.args as Args);\n }\n\n return snapshot.value.args as T;\n },\n validate: options.validate,\n autoSave: true,\n onSave(newArgs) {\n setArgsQueue.run(() => setBlockArgs(newArgs).then(unwrapResult));\n },\n });\n },\n /**\n * defaultUiState is temporarily here, remove it after implementing initialUiState\n */\n createUiModel<T extends UiState = UiState>(options: StateModelOptions<UiState, T> = {}, defaultUiState: () => UiState) {\n return createModel<T, UiState>({\n get() {\n if (options.transform) {\n return options.transform(snapshot.value.ui as UiState);\n }\n\n return (snapshot.value.ui ?? defaultUiState()) as T;\n },\n validate: options.validate,\n autoSave: true,\n onSave(newData) {\n setUiStateQueue.run(() => setBlockUiState(newData).then(unwrapResult));\n },\n });\n },\n /**\n * Retrieves the unwrapped values of outputs for the given keys.\n *\n * @template K - Keys of the outputs to unwrap.\n * @param keys - List of output names.\n * @throws Error if the outputs contain errors.\n * @returns An object with unwrapped output values.\n */\n unwrapOutputs<K extends keyof Outputs>(...keys: K[]): UnwrapOutputs<Outputs, K> {\n const outputs = snapshot.value.outputs as Partial<Readonly<Outputs>>;\n const entries = keys.map((key) => [key, unwrapValueOrErrors(outputs[key])]);\n return Object.fromEntries(entries);\n },\n /**\n * Updates the arguments state by applying a callback.\n *\n * @param cb - Callback to modify the current arguments.\n * @returns A promise resolving after the update is applied.\n */\n updateArgs(cb: (args: Args) => void): Promise<boolean> {\n const newArgs = cloneArgs();\n cb(newArgs);\n debug('updateArgs', newArgs);\n appModel.model.args = newArgs;\n return setArgsQueue.run(() => setBlockArgs(newArgs).then(unwrapResult));\n },\n /**\n * Updates the UI state by applying a callback.\n *\n * @param cb - Callback to modify the current UI state.\n * @returns A promise resolving after the update is applied.\n * @todo Make it mutable since there is already an initial one\n */\n updateUiState(cb: (args: UiState) => UiState): Promise<boolean> {\n const newUiState = cb(cloneUiState());\n debug('updateUiState', newUiState);\n appModel.model.ui = newUiState;\n return setUiStateQueue.run(() => setBlockUiState(newUiState).then(unwrapResult));\n },\n /**\n * Navigates to a specific href by updating the navigation state.\n *\n * @param href - The target href to navigate to.\n * @returns A promise resolving after the navigation state is updated.\n */\n navigateTo(href: Href) {\n const newState = cloneNavigationState();\n newState.href = href;\n return setNavigationStateQueue.run(() => setNavigationState(newState).then(unwrapResult));\n },\n async allSettled() {\n await delay(0);\n return setArgsAndUiStateQueue.allSettled();\n },\n };\n\n const getters = {\n closedRef,\n snapshot,\n queryParams: computed(() => parseQuery<Href>(snapshot.value.navigationState.href as Href)),\n href: computed(() => snapshot.value.navigationState.href),\n hasErrors: computed(() => Object.values(snapshot.value.outputs as Partial<Readonly<Outputs>>).some((v) => !v?.ok)),\n };\n\n const app = reactive(Object.assign(appModel, methods, getters));\n\n if (settings.debug) {\n // @ts-expect-error (to inspect in console in debug mode)\n globalThis.__block_app__ = app;\n }\n\n return app;\n}\n\nexport type BaseAppV2<\n Args = unknown,\n Outputs extends BlockOutputsBase = BlockOutputsBase,\n UiState = unknown,\n Href extends `/${string}` = `/${string}`,\n> = ReturnType<typeof createAppV2<Args, Outputs, UiState, Href>>;\n"],"names":["patchPoolingDelay","createNextAuthorMarker","marker","uniqueId","stringifyForDebug","v","err","createAppV2","state","platforma","settings","debug","msg","rest","r","error","data","nextAuthorMarker","closedRef","ref","uTagRef","debounceSpan","setArgsQueue","UpdateSerializer","setUiStateQueue","setArgsAndUiStateQueue","setNavigationStateQueue","snapshot","setBlockArgs","args","setBlockUiState","ui","setBlockArgsAndUiState","setNavigationState","outputs","computed","entries","k","vOrErr","outputErrors","MultiError","appModel","reactive","deepClone","ignoreUpdates","watchIgnorable","_newData","newData","unwrapResult","updateAppModel","patches","resolve","isAuthorChanged","_a","_b","applyPatch","hasAbortError","cloneArgs","cloneUiState","cloneNavigationState","methods","options","createModel","newArgs","defaultUiState","keys","key","unwrapValueOrErrors","cb","newUiState","href","newState","delay","getters","parseQuery","app"],"mappings":"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"}
|
package/dist/utils.js
CHANGED
|
@@ -1,58 +1,60 @@
|
|
|
1
1
|
var u = Object.defineProperty;
|
|
2
|
-
var f = (r,
|
|
3
|
-
var e = (r,
|
|
4
|
-
class
|
|
2
|
+
var f = (r, o, n) => o in r ? u(r, o, { enumerable: !0, configurable: !0, writable: !0, value: n }) : r[o] = n;
|
|
3
|
+
var e = (r, o, n) => f(r, typeof o != "symbol" ? o + "" : o, n);
|
|
4
|
+
class a extends Error {
|
|
5
5
|
constructor() {
|
|
6
6
|
super(...arguments);
|
|
7
7
|
e(this, "name", "UnresolvedError");
|
|
8
8
|
}
|
|
9
9
|
}
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
const l = (r) => Array.isArray(r) ? r : r ? [r] : [];
|
|
11
|
+
class c extends Error {
|
|
12
|
+
constructor(n) {
|
|
13
|
+
n = l(n);
|
|
14
|
+
super(n.map((t) => typeof t == "string" ? t : t.message).join(`
|
|
13
15
|
`));
|
|
14
16
|
e(this, "name", "MultiError");
|
|
15
17
|
e(this, "fullMessage");
|
|
16
|
-
this.errors =
|
|
18
|
+
this.errors = n, this.fullMessage = n.map((t) => typeof t == "string" ? t : t.type == "PlError" && "fullMessage" in t ? t.fullMessage : t.message).join(`
|
|
17
19
|
`);
|
|
18
20
|
}
|
|
19
21
|
}
|
|
20
|
-
function
|
|
22
|
+
function d(r) {
|
|
21
23
|
return {
|
|
22
24
|
ok: !0,
|
|
23
25
|
value: r
|
|
24
26
|
};
|
|
25
27
|
}
|
|
26
|
-
function
|
|
28
|
+
function p(r) {
|
|
27
29
|
if (!r)
|
|
28
|
-
throw new
|
|
30
|
+
throw new a();
|
|
29
31
|
if (!r.ok)
|
|
30
|
-
throw new
|
|
32
|
+
throw new c(r.errors);
|
|
31
33
|
return r.value;
|
|
32
34
|
}
|
|
33
|
-
function
|
|
35
|
+
function m(r) {
|
|
34
36
|
return {
|
|
35
37
|
value: r,
|
|
36
38
|
errors: void 0
|
|
37
39
|
};
|
|
38
40
|
}
|
|
39
|
-
function
|
|
41
|
+
function g(r) {
|
|
40
42
|
return r !== void 0;
|
|
41
43
|
}
|
|
42
|
-
const
|
|
43
|
-
const { formErrors:
|
|
44
|
-
return
|
|
44
|
+
const w = (r) => r, y = (r) => r instanceof Error ? r : Error(String(r)), M = (r) => r.name === "ZodError", j = (r) => {
|
|
45
|
+
const { formErrors: o, fieldErrors: n } = r.flatten(), t = Object.entries(n).map(([i, s]) => i + ":" + (s == null ? void 0 : s.join(",")));
|
|
46
|
+
return o.concat(t).join("; ");
|
|
45
47
|
};
|
|
46
48
|
export {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
49
|
+
c as MultiError,
|
|
50
|
+
a as UnresolvedError,
|
|
51
|
+
y as ensureError,
|
|
50
52
|
j as formatZodError,
|
|
51
|
-
|
|
52
|
-
|
|
53
|
+
w as identity,
|
|
54
|
+
g as isDefined,
|
|
53
55
|
M as isZodError,
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
56
|
+
p as unwrapValueOrErrors,
|
|
57
|
+
m as wrapOptionalResult,
|
|
58
|
+
d as wrapValueOrErrors
|
|
57
59
|
};
|
|
58
60
|
//# sourceMappingURL=utils.js.map
|
package/dist/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sources":["../src/utils.ts"],"sourcesContent":["import { type ErrorLike, type ValueOrErrors } from '@platforma-sdk/model';\nimport type { OptionalResult } from './types';\nimport type { ZodError } from 'zod';\n\nexport class UnresolvedError extends Error {\n name = 'UnresolvedError';\n}\n\n// @TODO use AggregateError\nexport class MultiError extends Error {\n name = 'MultiError';\n\n public readonly fullMessage: string;\n\n constructor(public readonly errors: (ErrorLike | string)[]) {\n super(errors.map((e) => typeof e == 'string' ? e : e.message).join('\\n'));\n this.fullMessage = errors.map((e) => {\n if (typeof e == 'string') {\n return e;\n } else if (e.type == 'PlError' && 'fullMessage' in e) {\n return e.fullMessage;\n }\n return e.message;\n }).join('\\n');\n }\n}\n\nexport function wrapValueOrErrors<V>(value: V): ValueOrErrors<V> {\n return {\n ok: true,\n value,\n };\n}\n\nexport function unwrapValueOrErrors<V>(valueOrErrors?: ValueOrErrors<V>): V {\n if (!valueOrErrors) {\n throw new UnresolvedError();\n }\n\n if (!valueOrErrors.ok) {\n throw new MultiError(valueOrErrors.errors);\n }\n\n return valueOrErrors.value;\n}\n\n// Optional Result\n\nexport function wrapOptionalResult<V>(value: V): OptionalResult<V> {\n return {\n value,\n errors: undefined,\n };\n}\n\nexport function isDefined<T>(v: T | undefined): v is T {\n return v !== undefined;\n}\n\nexport const identity = <T, V = T>(v: T): V => v as unknown as V;\n\nexport const ensureError = (cause: unknown) => {\n if (cause instanceof Error) {\n return cause;\n }\n\n return Error(String(cause));\n};\n\nexport const isZodError = (err: Error): err is ZodError => {\n return err.name === 'ZodError';\n};\n\nexport const formatZodError = (err: ZodError) => {\n const { formErrors, fieldErrors } = err.flatten();\n const _fieldErrors = Object.entries(fieldErrors).map(([field, errors]) => {\n return field + ':' + errors?.join(',');\n });\n return formErrors.concat(_fieldErrors).join('; ');\n};\n"],"names":["UnresolvedError","__publicField","MultiError","errors","e","wrapValueOrErrors","
|
|
1
|
+
{"version":3,"file":"utils.js","sources":["../src/utils.ts"],"sourcesContent":["import { type ErrorLike, type ValueOrErrors } from '@platforma-sdk/model';\nimport type { OptionalResult } from './types';\nimport type { ZodError } from 'zod';\n\nexport class UnresolvedError extends Error {\n name = 'UnresolvedError';\n}\n\nconst ensureArray = <T>(value: T | T[]): T[] => {\n return Array.isArray(value) ? value : value ? [value] : [];\n};\n\n// @TODO use AggregateError\nexport class MultiError extends Error {\n name = 'MultiError';\n\n public readonly fullMessage: string;\n\n constructor(public readonly errors: (ErrorLike | string)[]) {\n errors = ensureArray(errors);\n super(errors.map((e) => typeof e == 'string' ? e : e.message).join('\\n'));\n this.fullMessage = errors.map((e) => {\n if (typeof e == 'string') {\n return e;\n } else if (e.type == 'PlError' && 'fullMessage' in e) {\n return e.fullMessage;\n }\n return e.message;\n }).join('\\n');\n }\n}\n\nexport function wrapValueOrErrors<V>(value: V): ValueOrErrors<V> {\n return {\n ok: true,\n value,\n };\n}\n\nexport function unwrapValueOrErrors<V>(valueOrErrors?: ValueOrErrors<V>): V {\n if (!valueOrErrors) {\n throw new UnresolvedError();\n }\n\n if (!valueOrErrors.ok) {\n throw new MultiError(valueOrErrors.errors);\n }\n\n return valueOrErrors.value;\n}\n\n// Optional Result\n\nexport function wrapOptionalResult<V>(value: V): OptionalResult<V> {\n return {\n value,\n errors: undefined,\n };\n}\n\nexport function isDefined<T>(v: T | undefined): v is T {\n return v !== undefined;\n}\n\nexport const identity = <T, V = T>(v: T): V => v as unknown as V;\n\nexport const ensureError = (cause: unknown) => {\n if (cause instanceof Error) {\n return cause;\n }\n\n return Error(String(cause));\n};\n\nexport const isZodError = (err: Error): err is ZodError => {\n return err.name === 'ZodError';\n};\n\nexport const formatZodError = (err: ZodError) => {\n const { formErrors, fieldErrors } = err.flatten();\n const _fieldErrors = Object.entries(fieldErrors).map(([field, errors]) => {\n return field + ':' + errors?.join(',');\n });\n return formErrors.concat(_fieldErrors).join('; ');\n};\n"],"names":["UnresolvedError","__publicField","ensureArray","value","MultiError","errors","e","wrapValueOrErrors","unwrapValueOrErrors","valueOrErrors","wrapOptionalResult","isDefined","v","identity","ensureError","cause","isZodError","err","formatZodError","formErrors","fieldErrors","_fieldErrors","field"],"mappings":";;;AAIO,MAAMA,UAAwB,MAAM;AAAA,EAApC;AAAA;AACL,IAAAC,EAAA,cAAO;AAAA;AACT;AAEA,MAAMC,IAAc,CAAIC,MACf,MAAM,QAAQA,CAAK,IAAIA,IAAQA,IAAQ,CAACA,CAAK,IAAI,CAAA;AAInD,MAAMC,UAAmB,MAAM;AAAA,EAKpC,YAA4BC,GAAgC;AAC1D,IAAAA,IAASH,EAAYG,CAAM;AAC3B,UAAMA,EAAO,IAAI,CAACC,MAAM,OAAOA,KAAK,WAAWA,IAAIA,EAAE,OAAO,EAAE,KAAK;AAAA,CAAI,CAAC;AAN1E,IAAAL,EAAA,cAAO;AAES,IAAAA,EAAA;AAEY,SAAA,SAAAI,GAG1B,KAAK,cAAcA,EAAO,IAAI,CAACC,MACzB,OAAOA,KAAK,WACPA,IACEA,EAAE,QAAQ,aAAa,iBAAiBA,IAC1CA,EAAE,cAEJA,EAAE,OACV,EAAE,KAAK;AAAA,CAAI;AAAA,EACd;AACF;AAEO,SAASC,EAAqBJ,GAA4B;AAC/D,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,OAAAA;AAAA,EAAA;AAEJ;AAEO,SAASK,EAAuBC,GAAqC;AAC1E,MAAI,CAACA;AACH,UAAM,IAAIT,EAAA;AAGZ,MAAI,CAACS,EAAc;AACjB,UAAM,IAAIL,EAAWK,EAAc,MAAM;AAG3C,SAAOA,EAAc;AACvB;AAIO,SAASC,EAAsBP,GAA6B;AACjE,SAAO;AAAA,IACL,OAAAA;AAAA,IACA,QAAQ;AAAA,EAAA;AAEZ;AAEO,SAASQ,EAAaC,GAA0B;AACrD,SAAOA,MAAM;AACf;AAEO,MAAMC,IAAW,CAAWD,MAAYA,GAElCE,IAAc,CAACC,MACtBA,aAAiB,QACZA,IAGF,MAAM,OAAOA,CAAK,CAAC,GAGfC,IAAa,CAACC,MAClBA,EAAI,SAAS,YAGTC,IAAiB,CAACD,MAAkB;AAC/C,QAAM,EAAE,YAAAE,GAAY,aAAAC,MAAgBH,EAAI,QAAA,GAClCI,IAAe,OAAO,QAAQD,CAAW,EAAE,IAAI,CAAC,CAACE,GAAOjB,CAAM,MAC3DiB,IAAQ,OAAMjB,KAAA,gBAAAA,EAAQ,KAAK,KACnC;AACD,SAAOc,EAAW,OAAOE,CAAY,EAAE,KAAK,IAAI;AAClD;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@platforma-sdk/ui-vue",
|
|
3
|
-
"version": "1.43.
|
|
3
|
+
"version": "1.43.29",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"styles": "dist/index.js",
|
|
@@ -19,15 +19,15 @@
|
|
|
19
19
|
"ag-grid-enterprise": "^34.1.2",
|
|
20
20
|
"ag-grid-vue3": "^34.1.2",
|
|
21
21
|
"canonicalize": "~2.1.0",
|
|
22
|
-
"lru-cache": "^11.
|
|
22
|
+
"lru-cache": "^11.2.2",
|
|
23
23
|
"vue": "^3.5.13",
|
|
24
24
|
"@vueuse/core": "^13.3.0",
|
|
25
25
|
"@vueuse/integrations": "^13.3.0",
|
|
26
26
|
"d3-format": "^3.1.0",
|
|
27
27
|
"zod": "~3.23.8",
|
|
28
28
|
"@milaboratories/biowasm-tools": "2.0.0",
|
|
29
|
-
"@
|
|
30
|
-
"@
|
|
29
|
+
"@milaboratories/uikit": "2.4.20",
|
|
30
|
+
"@platforma-sdk/model": "1.43.29"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"happy-dom": "^15.11.7",
|
|
@@ -43,10 +43,10 @@
|
|
|
43
43
|
"fast-json-patch": "^3.1.1",
|
|
44
44
|
"@faker-js/faker": "^9.2.0",
|
|
45
45
|
"@milaboratories/build-configs": "1.0.8",
|
|
46
|
-
"@milaboratories/ts-builder": "1.0.5",
|
|
47
46
|
"@milaboratories/helpers": "1.9.0",
|
|
47
|
+
"@milaboratories/ts-configs": "1.0.6",
|
|
48
48
|
"@milaboratories/eslint-config": "1.0.4",
|
|
49
|
-
"@milaboratories/ts-
|
|
49
|
+
"@milaboratories/ts-builder": "1.0.5"
|
|
50
50
|
},
|
|
51
51
|
"scripts": {
|
|
52
52
|
"test": "vitest run --passWithNoTests",
|
|
@@ -242,7 +242,7 @@ export function createAppV1<
|
|
|
242
242
|
});
|
|
243
243
|
|
|
244
244
|
const outputErrors = computed<OutputErrors<Outputs>>(() => {
|
|
245
|
-
const entries = Object.entries(snapshot.outputs).map(([k, vOrErr]) => [k, vOrErr &&
|
|
245
|
+
const entries = Object.entries(snapshot.outputs).map(([k, vOrErr]) => [k, vOrErr && vOrErr.ok === false ? new MultiError(vOrErr.errors) : undefined]);
|
|
246
246
|
return Object.fromEntries(entries);
|
|
247
247
|
});
|
|
248
248
|
|
|
@@ -12,7 +12,7 @@ import { applyPatch } from 'fast-json-patch';
|
|
|
12
12
|
import { UpdateSerializer } from './UpdateSerializer';
|
|
13
13
|
import { watchIgnorable } from '@vueuse/core';
|
|
14
14
|
|
|
15
|
-
export const patchPoolingDelay =
|
|
15
|
+
export const patchPoolingDelay = 150;
|
|
16
16
|
|
|
17
17
|
export const createNextAuthorMarker = (marker: AuthorMarker | undefined): AuthorMarker => ({
|
|
18
18
|
authorId: marker?.authorId ?? uniqueId(),
|
|
@@ -122,7 +122,7 @@ export function createAppV2<
|
|
|
122
122
|
});
|
|
123
123
|
|
|
124
124
|
const outputErrors = computed<OutputErrors<Outputs>>(() => {
|
|
125
|
-
const entries = Object.entries(snapshot.value.outputs as Partial<Readonly<Outputs>>).map(([k, vOrErr]) => [k, vOrErr &&
|
|
125
|
+
const entries = Object.entries(snapshot.value.outputs as Partial<Readonly<Outputs>>).map(([k, vOrErr]) => [k, vOrErr && vOrErr.ok === false ? new MultiError(vOrErr.errors) : undefined]);
|
|
126
126
|
return Object.fromEntries(entries);
|
|
127
127
|
});
|
|
128
128
|
|
|
@@ -148,7 +148,7 @@ export function createAppV2<
|
|
|
148
148
|
() => appModel.model,
|
|
149
149
|
(_newData) => {
|
|
150
150
|
const newData = deepClone(_newData);
|
|
151
|
-
debug('setArgsAndUiStateQueue appModel.model', newData);
|
|
151
|
+
debug('setArgsAndUiStateQueue appModel.model, args', newData.args, 'ui', newData.ui);
|
|
152
152
|
setArgsAndUiStateQueue.run(() => setBlockArgsAndUiState(newData.args, newData.ui).then(unwrapResult));
|
|
153
153
|
},
|
|
154
154
|
{ deep: true },
|
|
@@ -192,7 +192,7 @@ export function createAppV2<
|
|
|
192
192
|
|
|
193
193
|
// Immutable behavior, apply external changes to the snapshot
|
|
194
194
|
if (isAuthorChanged || data.isExternalSnapshot) {
|
|
195
|
-
debug('got external changes, applying them to the snapshot',
|
|
195
|
+
debug('got external changes, applying them to the snapshot', patches.value);
|
|
196
196
|
ignoreUpdates(() => {
|
|
197
197
|
snapshot.value = applyPatch(snapshot.value, patches.value, false, false).newDocument;
|
|
198
198
|
updateAppModel({ args: snapshot.value.args, ui: snapshot.value.ui });
|
|
@@ -200,7 +200,10 @@ export function createAppV2<
|
|
|
200
200
|
});
|
|
201
201
|
} else {
|
|
202
202
|
// Mutable behavior
|
|
203
|
-
|
|
203
|
+
debug('outputs changed', patches.value);
|
|
204
|
+
ignoreUpdates(() => {
|
|
205
|
+
snapshot.value = applyPatch(snapshot.value, patches.value).newDocument;
|
|
206
|
+
});
|
|
204
207
|
}
|
|
205
208
|
|
|
206
209
|
await new Promise((resolve) => setTimeout(resolve, patchPoolingDelay));
|
|
@@ -323,7 +326,14 @@ export function createAppV2<
|
|
|
323
326
|
hasErrors: computed(() => Object.values(snapshot.value.outputs as Partial<Readonly<Outputs>>).some((v) => !v?.ok)),
|
|
324
327
|
};
|
|
325
328
|
|
|
326
|
-
|
|
329
|
+
const app = reactive(Object.assign(appModel, methods, getters));
|
|
330
|
+
|
|
331
|
+
if (settings.debug) {
|
|
332
|
+
// @ts-expect-error (to inspect in console in debug mode)
|
|
333
|
+
globalThis.__block_app__ = app;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
return app;
|
|
327
337
|
}
|
|
328
338
|
|
|
329
339
|
export type BaseAppV2<
|
package/src/utils.ts
CHANGED
|
@@ -6,6 +6,10 @@ export class UnresolvedError extends Error {
|
|
|
6
6
|
name = 'UnresolvedError';
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
+
const ensureArray = <T>(value: T | T[]): T[] => {
|
|
10
|
+
return Array.isArray(value) ? value : value ? [value] : [];
|
|
11
|
+
};
|
|
12
|
+
|
|
9
13
|
// @TODO use AggregateError
|
|
10
14
|
export class MultiError extends Error {
|
|
11
15
|
name = 'MultiError';
|
|
@@ -13,6 +17,7 @@ export class MultiError extends Error {
|
|
|
13
17
|
public readonly fullMessage: string;
|
|
14
18
|
|
|
15
19
|
constructor(public readonly errors: (ErrorLike | string)[]) {
|
|
20
|
+
errors = ensureArray(errors);
|
|
16
21
|
super(errors.map((e) => typeof e == 'string' ? e : e.message).join('\n'));
|
|
17
22
|
this.fullMessage = errors.map((e) => {
|
|
18
23
|
if (typeof e == 'string') {
|