@lowdefy/engine 4.0.0-alpha.8 → 4.0.0-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/Actions.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2021 Lowdefy, Inc
2
+ Copyright 2020-2022 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -31,7 +31,7 @@ let Actions = class Actions {
31
31
  console.error(error);
32
32
  }
33
33
  }
34
- async callActionLoop({ actions , arrayIndices , block , event , responses }) {
34
+ async callActionLoop({ actions , arrayIndices , block , event , progress , responses }) {
35
35
  for (const [index, action] of actions.entries()){
36
36
  try {
37
37
  if (action.async === true) {
@@ -41,6 +41,7 @@ let Actions = class Actions {
41
41
  block,
42
42
  event,
43
43
  index,
44
+ progress,
44
45
  responses
45
46
  });
46
47
  } else {
@@ -50,6 +51,7 @@ let Actions = class Actions {
50
51
  block,
51
52
  event,
52
53
  index,
54
+ progress,
53
55
  responses
54
56
  });
55
57
  responses[action.id] = response;
@@ -63,7 +65,7 @@ let Actions = class Actions {
63
65
  }
64
66
  }
65
67
  }
66
- async callActions({ actions , arrayIndices , block , catchActions , event , eventName }) {
68
+ async callActions({ actions , arrayIndices , block , catchActions , event , eventName , progress }) {
67
69
  const startTimestamp = new Date();
68
70
  const responses = {};
69
71
  try {
@@ -72,7 +74,8 @@ let Actions = class Actions {
72
74
  arrayIndices,
73
75
  block,
74
76
  event,
75
- responses
77
+ responses,
78
+ progress
76
79
  });
77
80
  } catch (error) {
78
81
  console.error(error);
@@ -82,7 +85,8 @@ let Actions = class Actions {
82
85
  arrayIndices,
83
86
  block,
84
87
  event,
85
- responses
88
+ responses,
89
+ progress
86
90
  });
87
91
  } catch (errorCatch) {
88
92
  console.error(errorCatch);
@@ -122,7 +126,7 @@ let Actions = class Actions {
122
126
  success: true
123
127
  };
124
128
  }
125
- async callAction({ action , arrayIndices , block , event , index , responses }) {
129
+ async callAction({ action , arrayIndices , block , event , index , progress , responses }) {
126
130
  if (!this.actions[action.type]) {
127
131
  throw {
128
132
  error: new Error(`Invalid action type "${action.type}" at "${block.blockId}".`),
@@ -161,6 +165,7 @@ let Actions = class Actions {
161
165
  });
162
166
  try {
163
167
  response = await this.actions[action.type]({
168
+ globals: this.context._internal.lowdefy._internal.globals,
164
169
  methods: getActionMethods({
165
170
  actions: responses,
166
171
  arrayIndices,
@@ -168,10 +173,11 @@ let Actions = class Actions {
168
173
  context: this.context,
169
174
  event
170
175
  }),
171
- document: this.context._internal.lowdefy._internal.document,
172
- params: parsedAction.params,
173
- window: this.context._internal.lowdefy._internal.window
176
+ params: parsedAction.params
174
177
  });
178
+ if (progress) {
179
+ progress();
180
+ }
175
181
  } catch (error) {
176
182
  responses[action.id] = {
177
183
  error,
@@ -220,8 +226,7 @@ let Actions = class Actions {
220
226
  };
221
227
  }
222
228
  displayMessage({ defaultMessage , duration , hideExplicitly , message , status }) {
223
- let close = ()=>undefined
224
- ;
229
+ let close = ()=>undefined;
225
230
  if (hideExplicitly && message !== false || !hideExplicitly && !type.isNone(message)) {
226
231
  close = this.context._internal.lowdefy._internal.displayMessage({
227
232
  content: type.isString(message) ? message : defaultMessage,
package/dist/Blocks.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /* eslint-disable no-param-reassign */ /*
2
- Copyright 2020-2021 Lowdefy, Inc
2
+ Copyright 2020-2022 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -14,7 +14,6 @@
14
14
  limitations under the License.
15
15
  */ import { applyArrayIndices, get, serializer, swap, type } from '@lowdefy/helpers';
16
16
  import Events from './Events.js';
17
- import getFieldValues from './getFieldValues.js';
18
17
  let Blocks = class Blocks {
19
18
  loopBlocks(fn) {
20
19
  if (type.isObject(this.areas)) {
@@ -29,26 +28,39 @@ let Blocks = class Blocks {
29
28
  this.loopBlocks((block)=>{
30
29
  block.idPattern = block.id;
31
30
  block.blockIdPattern = block.blockId;
32
- block.fieldPattern = block.field;
33
31
  block.id = applyArrayIndices(this.arrayIndices, block.idPattern);
34
32
  block.blockId = applyArrayIndices(this.arrayIndices, block.blockIdPattern);
35
- block.field = !type.isNone(block.fieldPattern) ? applyArrayIndices(this.arrayIndices, block.fieldPattern) : block.blockId;
36
- this.context._internal.RootBlocks.map[block.id] = block;
37
- block.visible = type.isNone(block.visible) ? true : block.visible;
38
- block.required = type.isNone(block.required) ? false : block.required;
39
- block.validate = type.isArray(block.validate) ? block.validate : [];
33
+ // CAUTION:
34
+ // map is not a direct reference to all blocks, blocks with duplicate ids will be overwritten in map
35
+ // which can cause issues with ambiguous config during call method since it will call only the method
36
+ // of the last initialized block for the referenced id.
37
+ this.context._internal.RootBlocks.map[block.blockId] = block;
38
+ block.events = type.isNone(block.events) ? {} : block.events;
39
+ block.layout = type.isNone(block.layout) ? {} : block.layout;
40
+ block.loading = type.isNone(block.loading) ? false : block.loading;
40
41
  block.properties = type.isNone(block.properties) ? {} : block.properties;
42
+ block.required = type.isNone(block.required) ? false : block.required;
43
+ block.skeleton = type.isNone(block.skeleton) ? null : block.skeleton;
41
44
  block.style = type.isNone(block.style) ? {} : block.style;
42
- block.layout = type.isNone(block.layout) ? {} : block.layout;
43
- block.events = type.isNone(block.events) ? {} : block.events;
45
+ block.validate = type.isNone(block.validate) ? [] : block.validate;
46
+ block.visible = type.isNone(block.visible) ? true : block.visible;
44
47
  block.areasLayoutEval = {};
45
48
  block.layoutEval = {};
49
+ block.loadingEval = {};
46
50
  block.propertiesEval = {};
47
51
  block.requiredEval = {};
52
+ block.skeletonEval = {};
48
53
  block.styleEval = {};
49
54
  block.validationEval = {};
50
55
  block.visibleEval = {};
51
- block.meta = this.context._internal.lowdefy._internal.blockComponents[block.type].meta;
56
+ try {
57
+ block.meta = this.context._internal.lowdefy._internal.blockComponents[block.type].meta;
58
+ } catch (error) {
59
+ throw new Error(`Block type ${block.type} not found at ${block.blockId}. Check your plugins to make sure the block is installed. For more info, see https://docs.lowdefy.com/plugins.`);
60
+ }
61
+ if (block.meta?.category !== 'container' && block.meta?.category !== 'display' && block.meta?.category !== 'input' && block.meta?.category !== 'list') {
62
+ throw new Error(`Block type ${block.type}.meta.category must be either "container", "display", "input" or "list".`);
63
+ }
52
64
  if (!type.isNone(block.areas)) {
53
65
  block.areasLayout = {};
54
66
  Object.keys(block.areas).forEach((key)=>{
@@ -61,13 +73,11 @@ let Blocks = class Blocks {
61
73
  } else {
62
74
  block.areasLayout = {};
63
75
  }
64
- block.requestKeys = getFieldValues('_request', block.style, block.properties, block.validate, block.visible, block.required);
65
76
  block.methods = {};
66
77
  block.registerMethod = (methodName, method)=>{
67
78
  block.methods[methodName] = method;
68
79
  };
69
- // TODO: add callMethod on block to be used by actions and accessible in blocks
70
- if (get(block, 'meta.category') === 'list') {
80
+ if (block.meta.category === 'list') {
71
81
  // TODO: to initialize new object in array, the new value should be passed by method to unshiftItem and pushItem
72
82
  block.unshiftItem = ()=>{
73
83
  this.subBlocks[block.id].forEach((bl, i)=>{
@@ -84,7 +94,7 @@ let Blocks = class Blocks {
84
94
  block,
85
95
  initState: {}
86
96
  }));
87
- this.context._internal.State.set(block.field, undefined);
97
+ this.context._internal.State.set(block.blockId, undefined);
88
98
  // set block and subBlock values undefined, so as not to pass values to new blocks
89
99
  this.subBlocks[block.id][0].recSetUndefined();
90
100
  block.update = true;
@@ -152,10 +162,10 @@ let Blocks = class Blocks {
152
162
  this.context._internal.update();
153
163
  };
154
164
  }
155
- if (get(block, 'meta.category') === 'input') {
165
+ if (block.meta.category === 'input') {
156
166
  block.setValue = (value)=>{
157
167
  block.value = type.enforceType(block.meta.valueType, value);
158
- this.context._internal.State.set(block.field, block.value);
168
+ this.context._internal.State.set(block.blockId, block.value);
159
169
  block.update = true;
160
170
  this.context._internal.update();
161
171
  };
@@ -175,14 +185,14 @@ let Blocks = class Blocks {
175
185
  this.loopBlocks((block)=>{
176
186
  block.update = true;
177
187
  block.showValidation = false;
178
- if (get(block, 'meta.category') === 'input' || get(block, 'meta.category') === 'list') {
179
- let blockValue = get(initState, block.field);
188
+ if (block.meta.category === 'input' || block.meta.category === 'list') {
189
+ let blockValue = get(initState, block.blockId);
180
190
  if (type.isUndefined(blockValue)) {
181
191
  // default null value for block type
182
192
  blockValue = type.isUndefined(block.meta.initValue) ? type.enforceType(block.meta.valueType, null) : block.meta.initValue;
183
- this.context._internal.State.set(block.field, block.value);
193
+ this.context._internal.State.set(block.blockId, block.value);
184
194
  }
185
- if (get(block, 'meta.category') === 'list') {
195
+ if (block.meta.category === 'list') {
186
196
  // load list value into list blocks
187
197
  if (!type.isArray(this.subBlocks[block.id])) {
188
198
  this.subBlocks[block.id] = [];
@@ -206,7 +216,7 @@ let Blocks = class Blocks {
206
216
  } else {
207
217
  block.value = blockValue;
208
218
  }
209
- } else if (get(block, 'meta.category') === 'container') {
219
+ } else if (block.meta.category === 'container') {
210
220
  if (!type.isArray(this.subBlocks[block.id])) {
211
221
  this.subBlocks[block.id] = [];
212
222
  }
@@ -236,8 +246,10 @@ let Blocks = class Blocks {
236
246
  return serializer.serializeToString({
237
247
  areasLayoutEval: block.areasLayoutEval,
238
248
  layoutEval: block.layoutEval,
249
+ loadingEval: block.loadingEval,
239
250
  propertiesEval: block.propertiesEval,
240
251
  requiredEval: block.requiredEval,
252
+ skeletonEval: block.skeletonEval,
241
253
  styleEval: block.styleEval,
242
254
  validationEval: block.validationEval,
243
255
  value: block.value,
@@ -248,7 +260,7 @@ let Blocks = class Blocks {
248
260
  let repeat = false;
249
261
  this.loopBlocks((block)=>{
250
262
  if (block.meta.category === 'input') {
251
- const stateValue = get(this.context.state, block.field);
263
+ const stateValue = get(this.context.state, block.blockId);
252
264
  // TODO: related to #345
253
265
  // enforce type here? should we reassign value here??
254
266
  block.value = type.isUndefined(stateValue) ? block.value : stateValue;
@@ -346,13 +358,23 @@ let Blocks = class Blocks {
346
358
  location: block.blockId,
347
359
  arrayIndices: this.arrayIndices
348
360
  });
361
+ block.loadingEval = this.context._internal.parser.parse({
362
+ input: block.loading,
363
+ location: block.blockId,
364
+ arrayIndices: this.arrayIndices
365
+ });
366
+ block.skeletonEval = this.context._internal.parser.parse({
367
+ input: block.skeleton,
368
+ location: block.blockId,
369
+ arrayIndices: this.arrayIndices
370
+ });
349
371
  block.areasLayoutEval = this.context._internal.parser.parse({
350
372
  input: block.areasLayout,
351
373
  location: block.blockId,
352
374
  arrayIndices: this.arrayIndices
353
375
  });
354
376
  }
355
- if (get(block, 'meta.category') === 'container' || get(block, 'meta.category') === 'list') {
377
+ if (block.meta.category === 'container' || block.meta.category === 'list') {
356
378
  if (this.subBlocks[block.id] && this.subBlocks[block.id].length > 0) {
357
379
  this.subBlocks[block.id].forEach((blockClass)=>{
358
380
  repeat = blockClass.recEval(block.visibleEval.output) || repeat;
@@ -372,25 +394,25 @@ let Blocks = class Blocks {
372
394
  const toDelete = new Set();
373
395
  this.loopBlocks((block)=>{
374
396
  if (block.visibleEval.output !== false) {
375
- if (get(block, 'meta.category') === 'container' || get(block, 'meta.category') === 'list') {
397
+ if (block.meta.category === 'container' || block.meta.category === 'list') {
376
398
  if (this.subBlocks[block.id] && this.subBlocks[block.id].length > 0) {
377
399
  this.subBlocks[block.id].forEach((blockClass)=>{
378
400
  blockClass.updateState();
379
401
  });
380
402
  } else {
381
- toSet.add(block.field);
382
- this.context._internal.State.set(block.field, type.enforceType(block.meta.valueType, null));
403
+ toSet.add(block.blockId);
404
+ this.context._internal.State.set(block.blockId, type.enforceType(block.meta.valueType, null));
383
405
  }
384
- } else if (get(block, 'meta.category') === 'input') {
385
- toSet.add(block.field);
386
- this.context._internal.State.set(block.field, block.value);
406
+ } else if (block.meta.category === 'input') {
407
+ toSet.add(block.blockId);
408
+ this.context._internal.State.set(block.blockId, block.value);
387
409
  }
388
- } else if (get(block, 'meta.category') === 'container') {
410
+ } else if (block.meta.category === 'container') {
389
411
  this.subBlocks[block.id].forEach((blockClass)=>{
390
412
  blockClass.recContainerDelState(toDelete);
391
413
  });
392
414
  } else {
393
- toDelete.add(block.field);
415
+ toDelete.add(block.blockId);
394
416
  }
395
417
  });
396
418
  toDelete.forEach((field)=>{
@@ -401,12 +423,12 @@ let Blocks = class Blocks {
401
423
  }
402
424
  recContainerDelState(toDelete) {
403
425
  this.loopBlocks((block)=>{
404
- if (get(block, 'meta.category') === 'container') {
426
+ if (block.meta.category === 'container') {
405
427
  this.subBlocks[block.id].forEach((blockClass)=>{
406
428
  blockClass.recContainerDelState(toDelete);
407
429
  });
408
430
  } else {
409
- toDelete.add(block.field);
431
+ toDelete.add(block.blockId);
410
432
  }
411
433
  });
412
434
  }
@@ -426,7 +448,6 @@ let Blocks = class Blocks {
426
448
  this.loopBlocks((block)=>{
427
449
  block.blockId = applyArrayIndices(this.arrayIndices, block.blockIdPattern);
428
450
  this.context._internal.RootBlocks.map[block.blockId] = block;
429
- block.field = !type.isNone(block.fieldPattern) ? applyArrayIndices(this.arrayIndices, block.fieldPattern) : block.blockId;
430
451
  });
431
452
  Object.keys(this.subBlocks).forEach((subKey)=>{
432
453
  this.subBlocks[subKey].forEach((subBlock)=>{
@@ -456,7 +477,7 @@ let Blocks = class Blocks {
456
477
  }
457
478
  recSetUndefined() {
458
479
  this.loopBlocks((block)=>{
459
- this.context._internal.State.set(block.field, undefined);
480
+ this.context._internal.State.set(block.blockId, undefined);
460
481
  });
461
482
  Object.keys(this.subBlocks).forEach((subKey)=>{
462
483
  this.subBlocks[subKey].forEach((subBlock)=>{
@@ -505,12 +526,12 @@ let Blocks = class Blocks {
505
526
  this.loopBlocks((block)=>{
506
527
  if (block.update) {
507
528
  block.update = false;
508
- block.loading = block.requestKeys.reduce((acc, key)=>acc || (this.context.requests[key] ? this.context.requests[key].loading : true)
509
- , false);
510
529
  block.eval = {
511
530
  areas: block.areasLayoutEval.output,
512
531
  events: type.isNone(block.Events.events) ? null : block.Events.events,
513
532
  properties: block.propertiesEval.output,
533
+ loading: block.loadingEval.output,
534
+ skeleton: block.skeletonEval.output,
514
535
  required: block.requiredEval.output,
515
536
  layout: block.layoutEval.output,
516
537
  style: block.styleEval.output,
@@ -530,25 +551,10 @@ let Blocks = class Blocks {
530
551
  });
531
552
  });
532
553
  }
533
- setBlocksLoadingCache() {
534
- this.loopBlocks((block)=>{
535
- block.loading_prev = block.loading;
536
- block.loading = block.requestKeys.reduce((acc, key)=>acc || (this.context.requests[key] ? this.context.requests[key].loading : true)
537
- , false);
538
- if (block.loading_prev !== block.loading) {
539
- this.context._internal.lowdefy._internal.updateBlock(block.id);
540
- }
541
- });
542
- Object.keys(this.subBlocks).forEach((subKey)=>{
543
- this.subBlocks[subKey].forEach((subBlock)=>{
544
- subBlock.setBlocksLoadingCache();
545
- });
546
- });
547
- }
548
- constructor({ arrayIndices , areas , context }){
554
+ constructor({ arrayIndices =[] , areas , context }){
549
555
  this.id = Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 5);
550
556
  this.areas = serializer.copy(areas || []);
551
- this.arrayIndices = type.isArray(arrayIndices) ? arrayIndices : [];
557
+ this.arrayIndices = arrayIndices;
552
558
  this.context = context;
553
559
  this.map = {};
554
560
  this.recCount = 0;
@@ -565,7 +571,6 @@ let Blocks = class Blocks {
565
571
  this.resetValidation = this.resetValidation.bind(this);
566
572
  this.resetValidationRec = this.resetValidationRec.bind(this);
567
573
  this.setBlocksCache = this.setBlocksCache.bind(this);
568
- this.setBlocksLoadingCache = this.setBlocksLoadingCache.bind(this);
569
574
  this.update = this.update.bind(this);
570
575
  this.updateState = this.updateState.bind(this);
571
576
  this.updateStateFromRoot = this.updateStateFromRoot.bind(this);
package/dist/Events.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2021 Lowdefy, Inc
2
+ Copyright 2020-2022 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -31,7 +31,7 @@ let Events = class Events {
31
31
  registerEvent({ name , actions }) {
32
32
  this.events[name] = this.initEvent(actions);
33
33
  }
34
- async triggerEvent({ name , event }) {
34
+ async triggerEvent({ name , event , progress }) {
35
35
  const eventDescription = this.events[name];
36
36
  let result = {
37
37
  blockId: this.block.blockId,
@@ -57,7 +57,8 @@ let Events = class Events {
57
57
  block: this.block,
58
58
  catchActions: eventDescription.catchActions,
59
59
  event,
60
- eventName: name
60
+ eventName: name,
61
+ progress
61
62
  });
62
63
  eventDescription.history.unshift(res);
63
64
  this.context.eventLog.unshift(res);
package/dist/Requests.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2021 Lowdefy, Inc
2
+ Copyright 2020-2022 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -14,85 +14,85 @@
14
14
  limitations under the License.
15
15
  */ import { get, serializer, type } from '@lowdefy/helpers';
16
16
  let Requests = class Requests {
17
- callRequests({ actions , arrayIndices , event , params } = {}) {
17
+ callRequests({ actions , arrayIndices , blockId , event , params } = {}) {
18
18
  if (type.isObject(params) && params.all === true) {
19
19
  return Promise.all(Object.keys(this.requestConfig).map((requestId)=>this.callRequest({
20
- requestId,
20
+ arrayIndices,
21
+ blockId,
21
22
  event,
22
- arrayIndices
23
- })
24
- ));
23
+ requestId
24
+ })));
25
25
  }
26
26
  let requestIds = [];
27
27
  if (type.isString(params)) requestIds = [
28
28
  params
29
29
  ];
30
30
  if (type.isArray(params)) requestIds = params;
31
- return Promise.all(requestIds.map((requestId)=>this.callRequest({
31
+ const requests = requestIds.map((requestId)=>this.callRequest({
32
32
  actions,
33
33
  requestId,
34
+ blockId,
34
35
  event,
35
36
  arrayIndices
36
- })
37
- ));
37
+ }));
38
+ this.context._internal.update(); // update to render request reset
39
+ return Promise.all(requests);
38
40
  }
39
- callRequest({ actions , arrayIndices , event , requestId }) {
40
- const request = this.requestConfig[requestId];
41
- if (!request) {
41
+ async callRequest({ actions , arrayIndices , blockId , event , requestId }) {
42
+ const requestConfig = this.requestConfig[requestId];
43
+ if (!this.context.requests[requestId]) {
44
+ this.context.requests[requestId] = [];
45
+ }
46
+ if (!requestConfig) {
42
47
  const error = new Error(`Configuration Error: Request ${requestId} not defined on page.`);
43
- this.context.requests[requestId] = {
48
+ this.context.requests[requestId].unshift({
49
+ blockId: 'block_id',
50
+ error,
44
51
  loading: false,
45
- response: null,
46
- error: [
47
- error
48
- ]
49
- };
50
- return Promise.reject(error);
51
- }
52
- if (!this.context.requests[requestId]) {
53
- this.context.requests[requestId] = {
54
- loading: true,
55
- response: null,
56
- error: []
57
- };
52
+ requestId,
53
+ response: null
54
+ });
55
+ throw error;
58
56
  }
59
57
  const { output: payload , errors: parserErrors } = this.context._internal.parser.parse({
60
58
  actions,
61
59
  event,
62
60
  arrayIndices,
63
- input: request.payload,
61
+ input: requestConfig.payload,
64
62
  location: requestId
65
63
  });
66
- // TODO: We are throwing this error differently to the request does not exist error
67
64
  if (parserErrors.length > 0) {
68
65
  throw parserErrors[0];
69
66
  }
70
- return this.fetch({
67
+ const request = {
68
+ blockId,
69
+ loading: true,
70
+ payload,
71
71
  requestId,
72
- payload
73
- });
72
+ response: null
73
+ };
74
+ this.context.requests[requestId].unshift(request);
75
+ return this.fetch(request);
74
76
  }
75
- async fetch({ requestId , payload }) {
76
- this.context.requests[requestId].loading = true;
77
- if (this.context._internal.RootBlocks) {
78
- this.context._internal.RootBlocks.setBlocksLoadingCache();
79
- }
77
+ async fetch(request) {
78
+ request.loading = true;
80
79
  try {
81
80
  const response = await this.context._internal.lowdefy._internal.callRequest({
81
+ blockId: request.blockId,
82
82
  pageId: this.context.pageId,
83
- payload: serializer.serialize(payload),
84
- requestId
83
+ payload: serializer.serialize(request.payload),
84
+ requestId: request.requestId
85
85
  });
86
86
  const deserializedResponse = serializer.deserialize(get(response, 'response', {
87
87
  default: null
88
88
  }));
89
- this.context.requests[requestId].response = deserializedResponse;
90
- this.context.requests[requestId].loading = false;
89
+ request.response = deserializedResponse;
90
+ request.loading = false;
91
91
  this.context._internal.update();
92
92
  return deserializedResponse;
93
93
  } catch (error) {
94
- this.context.requests[requestId].error.unshift(error);
95
- this.context.requests[requestId].loading = false;
94
+ request.error = error;
95
+ request.loading = false;
96
96
  this.context._internal.update();
97
97
  throw error;
98
98
  }
package/dist/State.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2021 Lowdefy, Inc
2
+ Copyright 2020-2022 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2021 Lowdefy, Inc
2
+ Copyright 2020-2022 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2021 Lowdefy, Inc
2
+ Copyright 2020-2022 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2021 Lowdefy, Inc
2
+ Copyright 2020-2022 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2021 Lowdefy, Inc
2
+ Copyright 2020-2022 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2021 Lowdefy, Inc
2
+ Copyright 2020-2022 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2021 Lowdefy, Inc
2
+ Copyright 2020-2022 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2021 Lowdefy, Inc
2
+ Copyright 2020-2022 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2021 Lowdefy, Inc
2
+ Copyright 2020-2022 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2021 Lowdefy, Inc
2
+ Copyright 2020-2022 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2021 Lowdefy, Inc
2
+ Copyright 2020-2022 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2021 Lowdefy, Inc
2
+ Copyright 2020-2022 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -13,12 +13,17 @@
13
13
  See the License for the specific language governing permissions and
14
14
  limitations under the License.
15
15
  */ import getFromObject from './getFromObject.js';
16
+ import { urlQuery } from '@lowdefy/helpers';
16
17
  function createGetUrlQuery({ arrayIndices , blockId , context }) {
17
18
  return function getUrlQuery(params) {
19
+ const { window } = context._internal.lowdefy._internal.globals;
20
+ if (!window?.location) {
21
+ throw new Error(`Browser window.location not available for getUrlQuery. Received: ${JSON.stringify(params)} on blockId: ${blockId}.`);
22
+ }
18
23
  return getFromObject({
19
24
  arrayIndices,
20
25
  location: blockId,
21
- object: context._internal.lowdefy.urlQuery,
26
+ object: urlQuery.parse(window.location.search.slice(1)),
22
27
  method: 'getUrlQuery',
23
28
  params
24
29
  });
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2021 Lowdefy, Inc
2
+ Copyright 2020-2022 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2021 Lowdefy, Inc
2
+ Copyright 2020-2022 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2021 Lowdefy, Inc
2
+ Copyright 2020-2022 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2021 Lowdefy, Inc
2
+ Copyright 2020-2022 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -13,8 +13,8 @@
13
13
  See the License for the specific language governing permissions and
14
14
  limitations under the License.
15
15
  */ function createLogout({ context }) {
16
- return function logout() {
17
- return context._internal.lowdefy._internal.auth.logout();
16
+ return function logout(params) {
17
+ return context._internal.lowdefy._internal.auth.logout(params);
18
18
  };
19
19
  }
20
20
  export default createLogout;
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2021 Lowdefy, Inc
2
+ Copyright 2020-2022 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -12,11 +12,12 @@
12
12
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
13
  See the License for the specific language governing permissions and
14
14
  limitations under the License.
15
- */ function createRequest({ actions , arrayIndices , context , event }) {
15
+ */ function createRequest({ actions , arrayIndices , blockId , context , event }) {
16
16
  return async function request(params) {
17
17
  return await context._internal.Requests.callRequests({
18
18
  actions,
19
19
  arrayIndices,
20
+ blockId,
20
21
  event,
21
22
  params
22
23
  });
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2021 Lowdefy, Inc
2
+ Copyright 2020-2022 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -17,7 +17,6 @@ function createReset({ context }) {
17
17
  return function reset() {
18
18
  context._internal.State.resetState();
19
19
  context._internal.RootBlocks.reset(serializer.deserializeFromString(context._internal.State.frozenState));
20
- context._internal.update();
21
20
  };
22
21
  }
23
22
  export default createReset;
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2021 Lowdefy, Inc
2
+ Copyright 2020-2022 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2021 Lowdefy, Inc
2
+ Copyright 2020-2022 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -16,7 +16,7 @@
16
16
  const createSetGlobal = ({ arrayIndices , context })=>{
17
17
  return function setGlobal(params) {
18
18
  Object.keys(params).forEach((key)=>{
19
- set(context._internal.lowdefy._internal.lowdefyGlobal, applyArrayIndices(arrayIndices, key), params[key]);
19
+ set(context._internal.lowdefy.lowdefyGlobal, applyArrayIndices(arrayIndices, key), params[key]);
20
20
  });
21
21
  context._internal.RootBlocks.reset();
22
22
  context._internal.update();
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2021 Lowdefy, Inc
2
+ Copyright 2020-2022 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2021 Lowdefy, Inc
2
+ Copyright 2020-2022 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2021 Lowdefy, Inc
2
+ Copyright 2020-2022 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2021 Lowdefy, Inc
2
+ Copyright 2020-2022 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2021 Lowdefy, Inc
2
+ Copyright 2020-2022 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -23,8 +23,7 @@ function createLink({ backLink , disabledLink , lowdefy , newOriginLink , noLink
23
23
  !props.back,
24
24
  !props.home,
25
25
  !props.url
26
- ].filter((v)=>!v
27
- ).length > 1) {
26
+ ].filter((v)=>!v).length > 1) {
28
27
  throw Error(`Invalid Link: To avoid ambiguity, only one of 'back', 'home', 'pageId' or 'url' can be defined.`);
29
28
  }
30
29
  if (props.back === true) {
@@ -39,7 +38,7 @@ function createLink({ backLink , disabledLink , lowdefy , newOriginLink , noLink
39
38
  pathname,
40
39
  query,
41
40
  setInput: ()=>{
42
- lowdefy.inputs[`page:${lowdefy.home.pageId}`] = props.input || {};
41
+ lowdefy.inputs[`page:${lowdefy.home.pageId}`] = props.input ?? {};
43
42
  }
44
43
  });
45
44
  }
@@ -49,7 +48,7 @@ function createLink({ backLink , disabledLink , lowdefy , newOriginLink , noLink
49
48
  pathname: `/${props.pageId}`,
50
49
  query,
51
50
  setInput: ()=>{
52
- lowdefy.inputs[`page:${props.pageId}`] = props.input || {};
51
+ lowdefy.inputs[`page:${props.pageId}`] = props.input ?? {};
53
52
  }
54
53
  });
55
54
  }
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2021 Lowdefy, Inc
2
+ Copyright 2020-2022 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -15,8 +15,7 @@
15
15
  */ import { type } from '@lowdefy/helpers';
16
16
  const getBlockMatcher = (params)=>{
17
17
  let testParams = params;
18
- if (type.isNone(testParams)) return ()=>true
19
- ;
18
+ if (type.isNone(testParams)) return ()=>true;
20
19
  if (type.isString(testParams)) {
21
20
  testParams = {
22
21
  blockIds: [
@@ -43,8 +42,7 @@ const getBlockMatcher = (params)=>{
43
42
  ];
44
43
  }
45
44
  if (type.isArray(testParams.regex)) {
46
- testParams.regex = testParams.regex.map((regex)=>new RegExp(regex)
47
- );
45
+ testParams.regex = testParams.regex.map((regex)=>new RegExp(regex));
48
46
  }
49
47
  return (id)=>{
50
48
  if (testParams.blockIds === true || type.isArray(testParams.blockIds) && testParams.blockIds.includes(id)) {
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2021 Lowdefy, Inc
2
+ Copyright 2020-2022 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -33,17 +33,21 @@ const blockData = ({ areas , blockId , blocks , events , field , id , layout , p
33
33
  type,
34
34
  validate,
35
35
  visible
36
- })
37
- ;
38
- async function getContext({ config , lowdefy , development =false }) {
36
+ });
37
+ function getContext({ config , lowdefy , resetContext ={
38
+ reset: false,
39
+ setReset: ()=>undefined
40
+ } , }) {
39
41
  if (!config) {
40
42
  throw new Error('A page must be provided to get context.');
41
43
  }
42
44
  const { id } = config;
43
- if (lowdefy.contexts[id] && !development) {
45
+ if (lowdefy.contexts[id] && !resetContext.reset) {
46
+ // memoize context if already created, eg between page transitions, unless the reset flag is raised
44
47
  lowdefy.contexts[id]._internal.update();
45
48
  return lowdefy.contexts[id];
46
49
  }
50
+ resetContext.setReset(false); // lower context reset flag.
47
51
  if (!lowdefy.inputs[id]) {
48
52
  lowdefy.inputs[id] = {};
49
53
  }
@@ -64,7 +68,6 @@ async function getContext({ config , lowdefy , development =false }) {
64
68
  context: ctx,
65
69
  operators: lowdefy._internal.operators
66
70
  });
67
- await _internal.parser.init();
68
71
  _internal.State = new State(ctx);
69
72
  _internal.Actions = new Actions(ctx);
70
73
  _internal.Requests = new Requests(ctx);
@@ -82,14 +85,28 @@ async function getContext({ config , lowdefy , development =false }) {
82
85
  _internal.update = ()=>{
83
86
  _internal.RootBlocks.update();
84
87
  };
85
- await _internal.RootBlocks.map[ctx.id].triggerEvent({
86
- name: 'onInit'
87
- });
88
- _internal.update();
89
- _internal.State.freezeState();
90
- _internal.RootBlocks.map[ctx.id].triggerEvent({
91
- name: 'onInitAsync'
92
- });
88
+ _internal.runOnInit = async (progress)=>{
89
+ progress();
90
+ if (!_internal.onInitDone) {
91
+ await _internal.RootBlocks.areas.root.blocks[0].triggerEvent({
92
+ name: 'onInit',
93
+ progress
94
+ });
95
+ _internal.update();
96
+ _internal.State.freezeState();
97
+ _internal.onInitDone = true;
98
+ }
99
+ };
100
+ _internal.runOnInitAsync = async (progress)=>{
101
+ if (_internal.onInitDone && !_internal.onInitAsyncDone) {
102
+ await _internal.RootBlocks.areas.root.blocks[0].triggerEvent({
103
+ name: 'onInitAsync',
104
+ progress
105
+ });
106
+ _internal.onInitAsyncDone = true;
107
+ }
108
+ };
109
+ ctx._internal.update();
93
110
  lowdefy.contexts[id] = ctx;
94
111
  return ctx;
95
112
  }
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2021 Lowdefy, Inc
2
+ Copyright 2020-2022 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@lowdefy/engine",
3
- "version": "4.0.0-alpha.8",
4
- "licence": "Apache-2.0",
3
+ "version": "4.0.0-rc.0",
4
+ "license": "Apache-2.0",
5
5
  "description": "",
6
6
  "homepage": "https://lowdefy.com",
7
7
  "keywords": [
@@ -30,26 +30,28 @@
30
30
  "dist/*"
31
31
  ],
32
32
  "scripts": {
33
- "build": "yarn swc",
33
+ "build": "swc src --out-dir dist --config-file ../../.swcrc --delete-dir-on-start",
34
34
  "clean": "rm -rf dist",
35
- "prepare": "yarn build",
36
- "swc": "swc src --out-dir dist --config-file ../../.swcrc --delete-dir-on-start",
37
- "test:watch": "jest --coverage --watch",
38
- "test": "jest --coverage"
35
+ "prepublishOnly": "pnpm build",
36
+ "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js"
39
37
  },
40
38
  "dependencies": {
41
- "@lowdefy/helpers": "4.0.0-alpha.8",
42
- "@lowdefy/operators": "4.0.0-alpha.8"
39
+ "@lowdefy/helpers": "4.0.0-rc.0",
40
+ "@lowdefy/operators": "4.0.0-rc.0"
43
41
  },
44
42
  "devDependencies": {
45
- "@lowdefy/operators-js": "4.0.0-alpha.8",
46
- "@swc/cli": "0.1.55",
47
- "@swc/core": "1.2.135",
48
- "@swc/jest": "0.2.17",
49
- "jest": "27.5.1"
43
+ "@jest/globals": "28.1.0",
44
+ "@lowdefy/actions-core": "4.0.0-rc.0",
45
+ "@lowdefy/build": "4.0.0-rc.0",
46
+ "@lowdefy/operators-js": "4.0.0-rc.0",
47
+ "@lowdefy/operators-mql": "4.0.0-rc.0",
48
+ "@swc/cli": "0.1.57",
49
+ "@swc/core": "1.2.194",
50
+ "@swc/jest": "0.2.21",
51
+ "jest": "28.1.0"
50
52
  },
51
53
  "publishConfig": {
52
54
  "access": "public"
53
55
  },
54
- "gitHead": "9d56b83cf45e868afe3a1eeba750fe826eb74c8c"
56
+ "gitHead": "f6872d7ff6da421710096536fce7b2016ef8f35c"
55
57
  }
@@ -1,35 +0,0 @@
1
- /*
2
- Copyright 2020-2021 Lowdefy, Inc
3
-
4
- Licensed under the Apache License, Version 2.0 (the "License");
5
- you may not use this file except in compliance with the License.
6
- You may obtain a copy of the License at
7
-
8
- http://www.apache.org/licenses/LICENSE-2.0
9
-
10
- Unless required by applicable law or agreed to in writing, software
11
- distributed under the License is distributed on an "AS IS" BASIS,
12
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- See the License for the specific language governing permissions and
14
- limitations under the License.
15
- */ import { serializer } from '@lowdefy/helpers';
16
- function getFieldValues(operatorName, ...args) {
17
- const result = new Set();
18
- function reviver(key, value) {
19
- if (key === operatorName) {
20
- result.add(value);
21
- }
22
- return value;
23
- }
24
- [
25
- ...args
26
- ].forEach((element)=>{
27
- serializer.deserializeFromString(serializer.serializeToString(element), {
28
- reviver
29
- });
30
- });
31
- return [
32
- ...result
33
- ];
34
- }
35
- export default getFieldValues;