@platforma-sdk/ui-vue 1.14.22 → 1.15.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@platforma-sdk/ui-vue",
3
- "version": "1.14.22",
3
+ "version": "1.15.0",
4
4
  "type": "module",
5
5
  "main": "dist/lib.umd.cjs",
6
6
  "module": "dist/lib.js",
@@ -2,12 +2,26 @@ import { deepClone, throttle } from '@milaboratories/helpers';
2
2
  import type { Mutable } from '@milaboratories/helpers';
3
3
  import type { NavigationState, BlockOutputsBase, BlockState, Platforma } from '@platforma-sdk/model';
4
4
  import { reactive, nextTick, computed, watch } from 'vue';
5
- import type { UnwrapValueOrErrors, StateModelOptions, UnwrapOutputs, OptionalResult, OutputValues, OutputErrors, AppSettings } from '../types';
5
+ import type { StateModelOptions, UnwrapOutputs, OptionalResult, OutputValues, OutputErrors, AppSettings } from '../types';
6
6
  import { createModel } from '../createModel';
7
7
  import { createAppModel } from './createAppModel';
8
8
  import { parseQuery } from '../urls';
9
9
  import { MultiError, unwrapValueOrErrors } from '../utils';
10
10
 
11
+ /**
12
+ * Creates an application instance with reactive state management, outputs, and methods for state updates and navigation.
13
+ *
14
+ * @template Args - The type of arguments used in the application.
15
+ * @template Outputs - The type of block outputs extending `BlockOutputsBase`.
16
+ * @template UiState - The type of the UI state.
17
+ * @template Href - The type of navigation href, defaulting to a string starting with `/`.
18
+ *
19
+ * @param state - Initial state of the application, including args, outputs, UI state, and navigation state.
20
+ * @param platforma - A platform interface for interacting with block states.
21
+ * @param settings - Application settings, such as debug flags.
22
+ *
23
+ * @returns A reactive application object with methods, getters, and state.
24
+ */
11
25
  export function createApp<
12
26
  Args = unknown,
13
27
  Outputs extends BlockOutputsBase = BlockOutputsBase,
@@ -33,6 +47,9 @@ export function createApp<
33
47
 
34
48
  const setBlockArgsAndUiState = throttle(platforma.setBlockArgsAndUiState, throttleSpan);
35
49
 
50
+ /**
51
+ * Reactive snapshot of the application state, including args, outputs, UI state, and navigation state.
52
+ */
36
53
  const snapshot = reactive({
37
54
  args: Object.freeze(state.args),
38
55
  outputs: Object.freeze(state.outputs),
@@ -68,7 +85,7 @@ export function createApp<
68
85
  }
69
86
  });
70
87
 
71
- await nextTick(); // @todo remove
88
+ await nextTick();
72
89
  });
73
90
 
74
91
  const cloneArgs = () => deepClone(snapshot.args) as Args;
@@ -143,9 +160,12 @@ export function createApp<
143
160
  return data as OptionalResult<UnwrapOutputs<Outputs, K>>;
144
161
  },
145
162
  /**
146
- * @throws Error
147
- * @param keys
148
- * @returns
163
+ * Retrieves the unwrapped values of outputs for the given keys.
164
+ *
165
+ * @template K - Keys of the outputs to unwrap.
166
+ * @param keys - List of output names.
167
+ * @throws Error if the outputs contain errors.
168
+ * @returns An object with unwrapped output values.
149
169
  */
150
170
  unwrapOutputs<K extends keyof Outputs>(...keys: K[]): UnwrapOutputs<Outputs, K> {
151
171
  const outputs = snapshot.outputs;
@@ -153,52 +173,44 @@ export function createApp<
153
173
  return Object.fromEntries(entries);
154
174
  },
155
175
  /**
156
- * @deprecated use app.outputs.[fieldName] instead
157
- * @see outputs
176
+ * Updates the arguments state by applying a callback.
177
+ *
178
+ * @param cb - Callback to modify the current arguments.
179
+ * @returns A promise resolving after the update is applied.
158
180
  */
159
- getOutputField(key: keyof Outputs) {
160
- return snapshot.outputs[key];
161
- },
162
- /**
163
- * @deprecated use outputValues instead
164
- * @see outputValues
165
- */
166
- getOutputFieldOkOptional<K extends keyof Outputs>(key: K): UnwrapValueOrErrors<Outputs[K]> | undefined {
167
- console.warn('use reactive app.outputValues.fieldName instead instead of getOutputFieldOkOptional(fieldName)');
168
-
169
- const result = this.getOutputField(key);
170
-
171
- if (result && result.ok) {
172
- return result.value;
173
- }
174
-
175
- return undefined;
176
- },
177
- getOutputFieldErrorsOptional<K extends keyof Outputs>(key: K): string[] | undefined {
178
- console.warn('use reactive app.outputErrors.fieldName instead instead of getOutputFieldErrorsOptional(fieldName)');
179
-
180
- const result = this.getOutputField(key);
181
-
182
- if (result && !result.ok) {
183
- return result.errors;
184
- }
185
-
186
- return undefined;
187
- },
188
181
  updateArgs(cb: (args: Args) => void) {
189
182
  const newArgs = cloneArgs();
190
183
  cb(newArgs);
191
184
  return platforma.setBlockArgs(newArgs);
192
185
  },
193
- updateUiState(cb: (args: UiState) => UiState) {
186
+ /**
187
+ * Updates the UI state by applying a callback.
188
+ *
189
+ * @param cb - Callback to modify the current UI state.
190
+ * @returns A promise resolving after the update is applied.
191
+ * @todo Make it mutable since there is already an initial one
192
+ */
193
+ updateUiState(cb: (args: UiState) => UiState): Promise<void> {
194
194
  const newUiState = cloneUiState();
195
195
  return platforma.setBlockUiState(cb(newUiState));
196
196
  },
197
+ /**
198
+ * Updates the navigation state by applying a callback.
199
+ *
200
+ * @param cb - Callback to modify the current navigation state.
201
+ * @returns A promise resolving after the update is applied.
202
+ */
197
203
  updateNavigationState(cb: (args: Mutable<NavigationState<Href>>) => void) {
198
204
  const newState = cloneNavigationState();
199
205
  cb(newState);
200
206
  return platforma.setNavigationState(newState);
201
207
  },
208
+ /**
209
+ * Navigates to a specific href by updating the navigation state.
210
+ *
211
+ * @param href - The target href to navigate to.
212
+ * @returns A promise resolving after the navigation state is updated.
213
+ */
202
214
  navigateTo(href: Href) {
203
215
  const newState = cloneNavigationState();
204
216
  newState.href = href;
@@ -220,43 +232,10 @@ export function createApp<
220
232
  snapshot,
221
233
  queryParams: computed(() => parseQuery<Href>(snapshot.navigationState.href)),
222
234
  href: computed(() => snapshot.navigationState.href),
223
- hasErrors: computed(() => Object.values(snapshot.outputs).some((v) => !v?.ok)), // @TODO: there is middle-layer error, v sometimes is undefined
224
-
225
- /** @deprecated */
226
- outputValues: computed(() => {
227
- console.warn('Change app.outputValues to app.model.outputs');
228
- return outputs.value;
229
- }),
230
-
231
- /** @deprecated */
232
- outputErrors: computed(() => {
233
- console.warn('Change app.outputErrors to app.model.outputErrors');
234
- return outputErrors.value;
235
- }),
236
-
237
- /** @deprecated */
238
- args: computed(() => {
239
- console.warn('Change app.args to app.snapshot.args');
240
- return snapshot.args;
241
- }),
242
- /** @deprecated */
243
- outputs: computed(() => {
244
- console.warn('Change app.outputs to app.snapshot.outputs');
245
- return snapshot.outputs;
246
- }),
247
- /** @deprecated */
248
- ui: computed(() => {
249
- console.warn('Change app.ui to app.snapshot.ui');
250
- return snapshot.ui;
251
- }),
252
- /** @deprecated */
253
- navigationState: computed(() => {
254
- console.warn('Change app.navigationState to app.snapshot.navigationState');
255
- return snapshot.navigationState;
256
- }),
235
+ hasErrors: computed(() => Object.values(snapshot.outputs).some((v) => !v?.ok)),
257
236
  };
258
237
 
259
- const appModel = createAppModel(
238
+ const model = createAppModel(
260
239
  {
261
240
  get() {
262
241
  return { args: snapshot.args, ui: snapshot.ui } as AppModel;
@@ -273,7 +252,7 @@ export function createApp<
273
252
  settings,
274
253
  );
275
254
 
276
- return reactive(Object.assign(appModel, methods, getters));
255
+ return reactive(Object.assign(model, methods, getters));
277
256
  }
278
257
 
279
258
  export type BaseApp<
@@ -81,12 +81,8 @@ const local = () => {
81
81
 
82
82
  type ExtApp = App<1, BlockOutputsBase, unknown, '/', ReturnType<typeof local>>;
83
83
 
84
- declare const _app: ExtApp;
85
-
86
84
  type _UpdateArgsParams = Parameters<Parameters<_App1['updateArgs']>[0]>[0];
87
85
 
88
- type _ccc = _App1['model']['args'];
89
-
90
86
  type __cases = [
91
87
  Expect<Equal<Model<string>, typeof __model1>>,
92
88
  Expect<Equal<Model<number>, typeof __model2>>,
@@ -96,10 +92,10 @@ type __cases = [
96
92
  Expect<Equal<ExtApp['counter'], number>>,
97
93
  Expect<Equal<ExtApp['label'], string>>,
98
94
  Expect<Equal<ExtApp['method'], () => number>>,
99
- Expect<Equal<_App1['args'], Readonly<_Args>>>,
95
+ Expect<Equal<_App1['snapshot']['args'], Readonly<_Args>>>,
100
96
  Expect<Equal<_App1['model']['outputs']['sum'], number | undefined>>,
101
97
  Expect<Equal<_App1['model']['outputErrors']['sum'], Error | undefined>>,
102
- Expect<Equal<_App1['ui'], Readonly<_UiState>>>,
98
+ Expect<Equal<_App1['snapshot']['ui'], Readonly<_UiState>>>,
103
99
  Expect<Equal<_App1['model']['args'], _Args>>,
104
100
  Expect<Equal<_App1['model']['ui'], _UiState>>,
105
101
  Expect<Equal<_UpdateArgsParams, _Args>>,
package/src/utils.ts CHANGED
@@ -5,12 +5,12 @@ import canonicalize from 'canonicalize';
5
5
 
6
6
  export class UnresolvedError extends Error {}
7
7
 
8
+ // @TODO use AggregateError
8
9
  export class MultiError extends Error {
9
10
  constructor(public readonly errors: string[]) {
10
11
  super(errors.join('\n'));
11
12
  }
12
13
 
13
- // @todo
14
14
  toString() {
15
15
  return this.errors.join('\n');
16
16
  }
@@ -29,7 +29,7 @@ export function unwrapValueOrErrors<V>(valueOrErrors?: ValueOrErrors<V>): V {
29
29
  }
30
30
 
31
31
  if (!valueOrErrors.ok) {
32
- throw Error(valueOrErrors.errors.join(';'));
32
+ throw new MultiError(valueOrErrors.errors);
33
33
  }
34
34
 
35
35
  return valueOrErrors.value;