@ruiapp/rapid-core 0.1.35 → 0.1.37

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/index.js CHANGED
@@ -3339,8 +3339,12 @@ async function handler$h(plugin, ctx, options) {
3339
3339
  if (operation) {
3340
3340
  delete mergedInput.$operation;
3341
3341
  }
3342
+ const stateProperties = mergedInput.$stateProperties;
3343
+ if (stateProperties) {
3344
+ delete mergedInput.$stateProperties;
3345
+ }
3342
3346
  const entityManager = server.getEntityManager(options.singularCode);
3343
- const output = await entityManager.updateEntityById({ id: mergedInput.id, entityToSave: mergedInput, operation }, plugin);
3347
+ const output = await entityManager.updateEntityById({ id: mergedInput.id, entityToSave: mergedInput, operation, stateProperties }, plugin);
3344
3348
  ctx.output = output;
3345
3349
  }
3346
3350
 
@@ -5036,7 +5040,6 @@ class CronJobPlugin {
5036
5040
  }
5037
5041
 
5038
5042
  async function getStateMachineNextSnapshot(server, options) {
5039
- debugger;
5040
5043
  const { machineConfig, currentState, event } = options;
5041
5044
  machineConfig.initial = currentState;
5042
5045
  const machine = xstate.createMachine(machineConfig);
@@ -5256,36 +5259,45 @@ class StateMachinePlugin {
5256
5259
  */
5257
5260
  async beforeUpdateEntity(server, model, options, currentEntity) {
5258
5261
  const entity = options.entityToSave;
5262
+ const stateMachineEnabledProperties = [];
5259
5263
  for (const property of model.properties) {
5260
5264
  const isStateMachineEnabled = lodash.get(property.config, "stateMachine.enabled", false);
5261
- const isTransferControlEnabled = lodash.get(property.config, "stateMachine.transferControl", false);
5262
- if (isStateMachineEnabled && isTransferControlEnabled && !isNullOrUndefined(entity[property.code])) {
5263
- throw new Error(`You're not allowed to change '${property.code}' property directly when transfer control is enabled, do an operation instead.`);
5265
+ if (isStateMachineEnabled) {
5266
+ stateMachineEnabledProperties.push(property);
5267
+ const isTransferControlEnabled = lodash.get(property.config, "stateMachine.transferControl", false);
5268
+ if (isTransferControlEnabled && !isNullOrUndefined(entity[property.code])) {
5269
+ throw new Error(`You're not allowed to change '${property.code}' property directly when transfer control is enabled, do an operation instead.`);
5270
+ }
5264
5271
  }
5265
5272
  }
5266
5273
  if (!options.operation) {
5267
5274
  return;
5268
5275
  }
5269
- const stateMachineEnabledProperties = lodash.filter(model.properties, (property) => lodash.get(property.config, "stateMachine.enabled", false));
5270
- let stateMachineEnabledProperty = lodash.first(stateMachineEnabledProperties);
5271
- if (options.stateProperty) {
5272
- stateMachineEnabledProperty = lodash.find(stateMachineEnabledProperties, (property) => property.code === options.stateProperty);
5276
+ let statePropertiesToUpdate;
5277
+ const statePropertyCodes = options.stateProperties;
5278
+ if (statePropertyCodes && statePropertyCodes.length) {
5279
+ statePropertiesToUpdate = lodash.filter(stateMachineEnabledProperties, (property) => statePropertyCodes.includes(property.code));
5280
+ }
5281
+ else {
5282
+ statePropertiesToUpdate = stateMachineEnabledProperties;
5273
5283
  }
5274
- if (!stateMachineEnabledProperty) {
5284
+ if (!statePropertiesToUpdate.length) {
5275
5285
  throw new Error(`State machine property not found.`);
5276
5286
  }
5277
- const machineConfig = lodash.get(stateMachineEnabledProperty.config, "stateMachine.config", null);
5278
- if (!machineConfig) {
5279
- throw new Error(`State machine of property '${stateMachineEnabledProperty.code}' not configured.`);
5287
+ for (const statePropertyToUpdate of statePropertiesToUpdate) {
5288
+ const machineConfig = lodash.get(statePropertyToUpdate.config, "stateMachine.config", null);
5289
+ if (!machineConfig) {
5290
+ throw new Error(`State machine of property '${statePropertyToUpdate.code}' not configured.`);
5291
+ }
5292
+ machineConfig.id = getStateMachineCode(model, statePropertyToUpdate);
5293
+ const nextSnapshot = await getStateMachineNextSnapshot(server, {
5294
+ machineConfig,
5295
+ context: {},
5296
+ currentState: currentEntity[statePropertyToUpdate.code],
5297
+ event: options.operation,
5298
+ });
5299
+ entity[statePropertyToUpdate.code] = nextSnapshot.value;
5280
5300
  }
5281
- machineConfig.id = getStateMachineCode(model, stateMachineEnabledProperty);
5282
- const nextSnapshot = await getStateMachineNextSnapshot(server, {
5283
- machineConfig,
5284
- context: {},
5285
- currentState: currentEntity[stateMachineEnabledProperty.code],
5286
- event: options.operation,
5287
- });
5288
- entity[stateMachineEnabledProperty.code] = nextSnapshot.value;
5289
5301
  }
5290
5302
  }
5291
5303
  function getStateMachineCode(model, property) {
@@ -1,4 +1,4 @@
1
- import { MachineConfig } from "xstate";
1
+ import { AnyActorRef, AnyEventObject, EventObject, MachineConfig, MachineContext, MachineSnapshot, MetaObject, StateValue } from "xstate";
2
2
  export type PropertyStateMachineConfig = {
3
3
  enabled: boolean;
4
4
  config: MachineConfig<any, any>;
@@ -7,18 +7,25 @@ export type PropertyStateMachineConfig = {
7
7
  export type SendStateMachineEventOptions = {
8
8
  code: string;
9
9
  };
10
+ export type StateMachineEvent = AnyEventObject;
10
11
  export type SendStateMachineEventInput = {
11
12
  code?: string;
12
13
  context: any;
13
14
  currentState: string;
14
15
  event: StateMachineEvent;
15
16
  };
16
- export type StateMachineEvent = {
17
- type: string;
18
- };
19
17
  export type GetStateMachineNextSnapshotOptions = {
20
18
  machineConfig: MachineConfig<any, any>;
21
19
  context: any;
22
20
  currentState: string;
23
21
  event: StateMachineEvent;
24
22
  };
23
+ export type DefaultStateMachineSnapshot = MachineSnapshot<MachineContext, EventObject, Record<string, AnyActorRef | undefined>, StateValue, string, unknown, MetaObject>;
24
+ export type TryGetStateMachineNextSnapshotResult = TryGetStateMachineNextSnapshotPositiveResult | TryGetStateMachineNextSnapshotNegativeResult;
25
+ export type TryGetStateMachineNextSnapshotPositiveResult = {
26
+ canTransfer: true;
27
+ nextSnapshot: DefaultStateMachineSnapshot;
28
+ };
29
+ export type TryGetStateMachineNextSnapshotNegativeResult = {
30
+ canTransfer: false;
31
+ };
@@ -1,3 +1,4 @@
1
1
  import { IRpdServer } from "../../core/server";
2
- import { GetStateMachineNextSnapshotOptions } from "./StateMachinePluginTypes";
2
+ import { GetStateMachineNextSnapshotOptions, TryGetStateMachineNextSnapshotResult } from "./StateMachinePluginTypes";
3
3
  export declare function getStateMachineNextSnapshot(server: IRpdServer, options: GetStateMachineNextSnapshotOptions): Promise<import("xstate").MachineSnapshot<any, import("xstate").AnyEventObject, Record<string, import("xstate").AnyActorRef>, import("xstate").StateValue, string, unknown, import("xstate").MetaObject, never>>;
4
+ export declare function tryGetStateMachineNextSnapshot(server: IRpdServer, options: GetStateMachineNextSnapshotOptions): Promise<TryGetStateMachineNextSnapshotResult>;
package/dist/types.d.ts CHANGED
@@ -355,7 +355,7 @@ export interface UpdateEntityByIdOptions {
355
355
  id: any;
356
356
  entityToSave: any;
357
357
  operation?: any;
358
- stateProperty?: string;
358
+ stateProperties?: string[];
359
359
  }
360
360
  export interface DeleteEntityOptions {
361
361
  filters?: EntityFilterOptions[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ruiapp/rapid-core",
3
- "version": "0.1.35",
3
+ "version": "0.1.37",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -16,13 +16,17 @@ export async function handler(
16
16
  const mergedInput = mergeInput(defaultInput, input, fixedInput);
17
17
  logger.debug(`Running ${code} handler...`, { defaultInput, fixedInput, mergedInput });
18
18
 
19
-
20
19
  const operation = mergedInput.$operation;
21
20
  if (operation) {
22
21
  delete mergedInput.$operation;
23
22
  }
24
23
 
24
+ const stateProperties = mergedInput.$stateProperties;
25
+ if (stateProperties) {
26
+ delete mergedInput.$stateProperties;
27
+ }
28
+
25
29
  const entityManager = server.getEntityManager(options.singularCode);
26
- const output = await entityManager.updateEntityById({ id: mergedInput.id, entityToSave: mergedInput, operation }, plugin);
30
+ const output = await entityManager.updateEntityById({ id: mergedInput.id, entityToSave: mergedInput, operation, stateProperties }, plugin);
27
31
  ctx.output = output;
28
32
  }
@@ -127,12 +127,17 @@ class StateMachinePlugin implements RapidPlugin {
127
127
  async beforeUpdateEntity(server: IRpdServer, model: RpdDataModel, options: UpdateEntityByIdOptions, currentEntity: any) {
128
128
  const entity = options.entityToSave;
129
129
 
130
+ const stateMachineEnabledProperties: RpdDataModelProperty[] = [];
130
131
  for (const property of model.properties) {
131
132
  const isStateMachineEnabled = get(property.config, "stateMachine.enabled", false);
132
- const isTransferControlEnabled = get(property.config, "stateMachine.transferControl", false);
133
- if (isStateMachineEnabled && isTransferControlEnabled && !isNullOrUndefined(entity[property.code])
134
- ) {
135
- throw new Error(`You're not allowed to change '${property.code}' property directly when transfer control is enabled, do an operation instead.`);
133
+
134
+ if (isStateMachineEnabled) {
135
+ stateMachineEnabledProperties.push(property);
136
+
137
+ const isTransferControlEnabled = get(property.config, "stateMachine.transferControl", false);
138
+ if (isTransferControlEnabled && !isNullOrUndefined(entity[property.code])) {
139
+ throw new Error(`You're not allowed to change '${property.code}' property directly when transfer control is enabled, do an operation instead.`);
140
+ }
136
141
  }
137
142
  }
138
143
 
@@ -140,32 +145,35 @@ class StateMachinePlugin implements RapidPlugin {
140
145
  return;
141
146
  }
142
147
 
143
- const stateMachineEnabledProperties = filter(model.properties, (property) => get(property.config, "stateMachine.enabled", false)) as RpdDataModelProperty[];
144
- let stateMachineEnabledProperty = first(stateMachineEnabledProperties);
145
- if (options.stateProperty) {
146
- stateMachineEnabledProperty = find(stateMachineEnabledProperties, (property) => property.code === options.stateProperty);
148
+ let statePropertiesToUpdate: RpdDataModelProperty[];
149
+ const statePropertyCodes = options.stateProperties;
150
+ if (statePropertyCodes && statePropertyCodes.length) {
151
+ statePropertiesToUpdate = filter(stateMachineEnabledProperties, (property) => statePropertyCodes.includes(property.code));
152
+ } else {
153
+ statePropertiesToUpdate = stateMachineEnabledProperties;
147
154
  }
148
155
 
149
- if (!stateMachineEnabledProperty) {
156
+ if (!statePropertiesToUpdate.length) {
150
157
  throw new Error(`State machine property not found.`);
151
158
  }
152
159
 
153
- const machineConfig = get(stateMachineEnabledProperty.config, "stateMachine.config", null);
154
- if (!machineConfig) {
155
- throw new Error(`State machine of property '${stateMachineEnabledProperty.code}' not configured.`);
160
+ for (const statePropertyToUpdate of statePropertiesToUpdate) {
161
+ const machineConfig = get(statePropertyToUpdate.config, "stateMachine.config", null);
162
+ if (!machineConfig) {
163
+ throw new Error(`State machine of property '${statePropertyToUpdate.code}' not configured.`);
164
+ }
165
+ machineConfig.id = getStateMachineCode(model, statePropertyToUpdate);
166
+
167
+ const nextSnapshot = await getStateMachineNextSnapshot(server, {
168
+ machineConfig,
169
+ context: {},
170
+ currentState: currentEntity[statePropertyToUpdate.code],
171
+ event: options.operation,
172
+ });
173
+
174
+ entity[statePropertyToUpdate.code] = nextSnapshot.value;
156
175
  }
157
- machineConfig.id = getStateMachineCode(model, stateMachineEnabledProperty);
158
-
159
- const nextSnapshot = await getStateMachineNextSnapshot(server, {
160
- machineConfig,
161
- context: {},
162
- currentState: currentEntity[stateMachineEnabledProperty.code],
163
- event: options.operation,
164
- });
165
-
166
- entity[stateMachineEnabledProperty.code] = nextSnapshot.value;
167
176
  }
168
-
169
177
  }
170
178
 
171
179
  function getStateMachineCode(model: RpdDataModel, property: RpdDataModelProperty) {
@@ -1,4 +1,4 @@
1
- import { MachineConfig } from "xstate";
1
+ import { AnyActorRef, AnyEventObject, EventObject, MachineConfig, MachineContext, MachineSnapshot, MetaObject, StateValue } from "xstate";
2
2
 
3
3
 
4
4
  export type PropertyStateMachineConfig = {
@@ -11,6 +11,8 @@ export type SendStateMachineEventOptions = {
11
11
  code: string;
12
12
  }
13
13
 
14
+ export type StateMachineEvent = AnyEventObject;
15
+
14
16
  export type SendStateMachineEventInput = {
15
17
  code?: string;
16
18
  context: any;
@@ -18,13 +20,22 @@ export type SendStateMachineEventInput = {
18
20
  event: StateMachineEvent;
19
21
  }
20
22
 
21
- export type StateMachineEvent = {
22
- type: string;
23
- }
24
-
25
23
  export type GetStateMachineNextSnapshotOptions = {
26
24
  machineConfig: MachineConfig<any, any>;
27
25
  context: any;
28
26
  currentState: string;
29
27
  event: StateMachineEvent;
28
+ }
29
+
30
+ export type DefaultStateMachineSnapshot = MachineSnapshot<MachineContext, EventObject, Record<string, AnyActorRef | undefined>, StateValue, string, unknown, MetaObject>;
31
+
32
+ export type TryGetStateMachineNextSnapshotResult = TryGetStateMachineNextSnapshotPositiveResult | TryGetStateMachineNextSnapshotNegativeResult;
33
+
34
+ export type TryGetStateMachineNextSnapshotPositiveResult = {
35
+ canTransfer: true;
36
+ nextSnapshot: DefaultStateMachineSnapshot;
37
+ }
38
+
39
+ export type TryGetStateMachineNextSnapshotNegativeResult = {
40
+ canTransfer: false;
30
41
  }
@@ -1,9 +1,8 @@
1
1
  import { IRpdServer } from "~/core/server";
2
- import { GetStateMachineNextSnapshotOptions } from "./StateMachinePluginTypes";
2
+ import { DefaultStateMachineSnapshot, GetStateMachineNextSnapshotOptions, TryGetStateMachineNextSnapshotResult } from "./StateMachinePluginTypes";
3
3
  import { createMachine, getInitialSnapshot, getNextSnapshot } from "xstate";
4
4
 
5
5
  export async function getStateMachineNextSnapshot(server: IRpdServer, options: GetStateMachineNextSnapshotOptions) {
6
- debugger
7
6
  const { machineConfig, currentState, event } = options;
8
7
  machineConfig.initial = currentState;
9
8
 
@@ -17,3 +16,22 @@ export async function getStateMachineNextSnapshot(server: IRpdServer, options: G
17
16
  const nextSnapshot = getNextSnapshot(machine, snapshot, event);
18
17
  return nextSnapshot;
19
18
  }
19
+
20
+ export async function tryGetStateMachineNextSnapshot(server: IRpdServer, options: GetStateMachineNextSnapshotOptions): Promise<TryGetStateMachineNextSnapshotResult> {
21
+ const { machineConfig, currentState, event } = options;
22
+ machineConfig.initial = currentState;
23
+
24
+ const machine = createMachine(machineConfig);
25
+ const snapshot = getInitialSnapshot(machine);
26
+
27
+ const canTransfer = snapshot.can(event);
28
+ let nextSnapshot: DefaultStateMachineSnapshot;
29
+ if (canTransfer) {
30
+ nextSnapshot = getNextSnapshot(machine, snapshot, event);
31
+ }
32
+
33
+ return {
34
+ canTransfer,
35
+ nextSnapshot,
36
+ };
37
+ }
package/src/types.ts CHANGED
@@ -474,7 +474,7 @@ export interface UpdateEntityByIdOptions {
474
474
  id: any;
475
475
  entityToSave: any;
476
476
  operation?: any;
477
- stateProperty?: string;
477
+ stateProperties?: string[];
478
478
  }
479
479
 
480
480
  export interface DeleteEntityOptions {