@snowtop/ent 0.1.0-alpha16 → 0.1.0-alpha160-test1

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.
Files changed (176) hide show
  1. package/action/action.d.ts +25 -14
  2. package/action/action.js +22 -7
  3. package/action/executor.d.ts +16 -3
  4. package/action/executor.js +89 -28
  5. package/action/experimental_action.d.ts +25 -16
  6. package/action/experimental_action.js +34 -14
  7. package/action/index.d.ts +4 -1
  8. package/action/index.js +7 -1
  9. package/action/operations.d.ts +126 -0
  10. package/action/operations.js +686 -0
  11. package/action/orchestrator.d.ts +43 -12
  12. package/action/orchestrator.js +461 -101
  13. package/action/relative_value.d.ts +47 -0
  14. package/action/relative_value.js +125 -0
  15. package/action/transaction.d.ts +10 -0
  16. package/action/transaction.js +23 -0
  17. package/auth/auth.d.ts +1 -1
  18. package/core/base.d.ts +56 -23
  19. package/core/base.js +7 -1
  20. package/core/clause.d.ts +103 -39
  21. package/core/clause.js +430 -66
  22. package/core/config.d.ts +13 -3
  23. package/core/config.js +10 -1
  24. package/core/const.d.ts +3 -0
  25. package/core/const.js +6 -0
  26. package/core/context.d.ts +6 -3
  27. package/core/context.js +22 -3
  28. package/core/convert.d.ts +1 -1
  29. package/core/date.js +1 -5
  30. package/core/db.d.ts +12 -8
  31. package/core/db.js +21 -9
  32. package/core/ent.d.ts +99 -95
  33. package/core/ent.js +550 -602
  34. package/core/global_schema.d.ts +7 -0
  35. package/core/global_schema.js +51 -0
  36. package/core/loaders/assoc_count_loader.d.ts +5 -2
  37. package/core/loaders/assoc_count_loader.js +19 -3
  38. package/core/loaders/assoc_edge_loader.d.ts +2 -3
  39. package/core/loaders/assoc_edge_loader.js +23 -17
  40. package/core/loaders/index.d.ts +1 -2
  41. package/core/loaders/index.js +1 -5
  42. package/core/loaders/loader.d.ts +3 -3
  43. package/core/loaders/loader.js +4 -21
  44. package/core/loaders/object_loader.d.ts +30 -9
  45. package/core/loaders/object_loader.js +226 -79
  46. package/core/loaders/query_loader.d.ts +7 -13
  47. package/core/loaders/query_loader.js +60 -24
  48. package/core/loaders/raw_count_loader.d.ts +1 -0
  49. package/core/loaders/raw_count_loader.js +8 -3
  50. package/core/logger.d.ts +1 -1
  51. package/core/logger.js +1 -0
  52. package/core/privacy.d.ts +26 -16
  53. package/core/privacy.js +68 -51
  54. package/core/query/assoc_query.d.ts +3 -2
  55. package/core/query/assoc_query.js +10 -2
  56. package/core/query/custom_clause_query.d.ts +29 -0
  57. package/core/query/custom_clause_query.js +105 -0
  58. package/core/query/custom_query.d.ts +19 -2
  59. package/core/query/custom_query.js +111 -13
  60. package/core/query/index.d.ts +1 -0
  61. package/core/query/index.js +3 -1
  62. package/core/query/query.d.ts +18 -4
  63. package/core/query/query.js +135 -58
  64. package/core/query/shared_assoc_test.d.ts +2 -1
  65. package/core/query/shared_assoc_test.js +186 -55
  66. package/core/query/shared_test.d.ts +9 -2
  67. package/core/query/shared_test.js +529 -236
  68. package/core/query_impl.d.ts +8 -0
  69. package/core/query_impl.js +28 -0
  70. package/core/viewer.d.ts +2 -0
  71. package/core/viewer.js +3 -1
  72. package/graphql/graphql.d.ts +108 -22
  73. package/graphql/graphql.js +183 -137
  74. package/graphql/graphql_field_helpers.d.ts +9 -3
  75. package/graphql/graphql_field_helpers.js +22 -2
  76. package/graphql/index.d.ts +2 -2
  77. package/graphql/index.js +5 -5
  78. package/graphql/query/connection_type.d.ts +9 -9
  79. package/graphql/query/shared_assoc_test.js +1 -1
  80. package/graphql/query/shared_edge_connection.js +1 -19
  81. package/graphql/scalars/orderby_direction.d.ts +2 -0
  82. package/graphql/scalars/orderby_direction.js +15 -0
  83. package/imports/dataz/example1/_auth.js +128 -47
  84. package/imports/dataz/example1/_viewer.js +87 -39
  85. package/imports/index.d.ts +7 -2
  86. package/imports/index.js +20 -5
  87. package/index.d.ts +23 -5
  88. package/index.js +35 -10
  89. package/package.json +19 -19
  90. package/parse_schema/parse.d.ts +33 -9
  91. package/parse_schema/parse.js +182 -33
  92. package/schema/base_schema.d.ts +13 -3
  93. package/schema/base_schema.js +13 -0
  94. package/schema/field.d.ts +78 -21
  95. package/schema/field.js +232 -72
  96. package/schema/index.d.ts +2 -2
  97. package/schema/index.js +7 -2
  98. package/schema/json_field.d.ts +16 -4
  99. package/schema/json_field.js +32 -2
  100. package/schema/schema.d.ts +109 -20
  101. package/schema/schema.js +42 -53
  102. package/schema/struct_field.d.ts +15 -3
  103. package/schema/struct_field.js +117 -22
  104. package/schema/union_field.d.ts +1 -1
  105. package/scripts/custom_compiler.js +12 -8
  106. package/scripts/custom_graphql.js +171 -64
  107. package/scripts/migrate_v0.1.js +36 -0
  108. package/scripts/move_types.js +120 -0
  109. package/scripts/read_schema.js +22 -7
  110. package/testutils/action/complex_schemas.d.ts +69 -0
  111. package/testutils/action/complex_schemas.js +405 -0
  112. package/testutils/builder.d.ts +37 -41
  113. package/testutils/builder.js +66 -46
  114. package/testutils/db/fixture.d.ts +10 -0
  115. package/testutils/db/fixture.js +26 -0
  116. package/testutils/db/{test_db.d.ts → temp_db.d.ts} +32 -8
  117. package/testutils/db/{test_db.js → temp_db.js} +251 -48
  118. package/testutils/db/value.d.ts +7 -0
  119. package/testutils/db/value.js +251 -0
  120. package/testutils/db_mock.d.ts +16 -4
  121. package/testutils/db_mock.js +52 -9
  122. package/testutils/db_time_zone.d.ts +4 -0
  123. package/testutils/db_time_zone.js +41 -0
  124. package/testutils/ent-graphql-tests/index.d.ts +7 -1
  125. package/testutils/ent-graphql-tests/index.js +56 -26
  126. package/testutils/fake_comms.js +1 -1
  127. package/testutils/fake_data/const.d.ts +2 -1
  128. package/testutils/fake_data/const.js +3 -0
  129. package/testutils/fake_data/fake_contact.d.ts +7 -3
  130. package/testutils/fake_data/fake_contact.js +13 -7
  131. package/testutils/fake_data/fake_event.d.ts +4 -1
  132. package/testutils/fake_data/fake_event.js +7 -6
  133. package/testutils/fake_data/fake_tag.d.ts +36 -0
  134. package/testutils/fake_data/fake_tag.js +89 -0
  135. package/testutils/fake_data/fake_user.d.ts +8 -5
  136. package/testutils/fake_data/fake_user.js +31 -19
  137. package/testutils/fake_data/index.js +5 -1
  138. package/testutils/fake_data/internal.d.ts +2 -0
  139. package/testutils/fake_data/internal.js +7 -1
  140. package/testutils/fake_data/tag_query.d.ts +13 -0
  141. package/testutils/fake_data/tag_query.js +48 -0
  142. package/testutils/fake_data/test_helpers.d.ts +14 -6
  143. package/testutils/fake_data/test_helpers.js +31 -15
  144. package/testutils/fake_data/user_query.d.ts +16 -6
  145. package/testutils/fake_data/user_query.js +72 -23
  146. package/testutils/fake_log.js +1 -1
  147. package/testutils/parse_sql.d.ts +6 -0
  148. package/testutils/parse_sql.js +16 -2
  149. package/testutils/test_edge_global_schema.d.ts +15 -0
  150. package/testutils/test_edge_global_schema.js +62 -0
  151. package/testutils/write.d.ts +2 -2
  152. package/testutils/write.js +33 -7
  153. package/tsc/ast.d.ts +15 -3
  154. package/tsc/ast.js +114 -23
  155. package/tsc/compilerOptions.js +5 -1
  156. package/tsc/move_generated.d.ts +1 -0
  157. package/tsc/move_generated.js +164 -0
  158. package/tsc/transform.d.ts +22 -0
  159. package/tsc/transform.js +182 -0
  160. package/tsc/transform_action.d.ts +22 -0
  161. package/tsc/transform_action.js +183 -0
  162. package/tsc/transform_ent.d.ts +17 -0
  163. package/tsc/transform_ent.js +60 -0
  164. package/tsc/transform_schema.d.ts +27 -0
  165. package/{scripts → tsc}/transform_schema.js +146 -117
  166. package/core/loaders/index_loader.d.ts +0 -14
  167. package/core/loaders/index_loader.js +0 -27
  168. package/graphql/enums.d.ts +0 -3
  169. package/graphql/enums.js +0 -25
  170. package/scripts/move_generated.js +0 -141
  171. package/scripts/transform_actions.js +0 -266
  172. package/scripts/transform_code.d.ts +0 -1
  173. package/scripts/transform_code.js +0 -111
  174. package/scripts/transform_schema.d.ts +0 -1
  175. /package/scripts/{move_generated.d.ts → migrate_v0.1.d.ts} +0 -0
  176. /package/scripts/{transform_actions.d.ts → move_types.d.ts} +0 -0
@@ -1,27 +1,34 @@
1
- import { Ent, EntConstructor, Viewer, ID, Data, PrivacyPolicy, Context } from "../core/base";
2
- import { DataOperation, AssocEdgeInputOptions } from "../core/ent";
1
+ import { Ent, EntConstructor, Viewer, ID, Data, PrivacyPolicy, Context, WriteOperation } from "../core/base";
2
+ import { DataOperation, AssocEdgeInputOptions } from "./operations";
3
3
  import { Queryer } from "../core/db";
4
4
  import { TransformedUpdateOperation, UpdateOperation } from "../schema";
5
- export declare enum WriteOperation {
6
- Insert = "insert",
7
- Edit = "edit",
8
- Delete = "delete"
5
+ import { FieldInfoMap } from "../schema/schema";
6
+ export { WriteOperation };
7
+ type MaybeNull<T extends Ent> = T | null;
8
+ type TMaybleNullableEnt<T extends Ent> = T | MaybeNull<T>;
9
+ interface BuilderOrchestrator {
10
+ __getOptions(): {
11
+ fieldInfo: FieldInfoMap;
12
+ };
9
13
  }
10
- declare type MaybeNull<T extends Ent> = T | null;
11
- declare type TMaybleNullableEnt<T extends Ent> = T | MaybeNull<T>;
12
14
  export interface Builder<TEnt extends Ent<TViewer>, TViewer extends Viewer = Viewer, TExistingEnt extends TMaybleNullableEnt<TEnt> = MaybeNull<TEnt>> {
13
15
  existingEnt: TExistingEnt;
14
16
  ent: EntConstructor<TEnt, TViewer>;
15
17
  placeholderID: ID;
16
18
  readonly viewer: TViewer;
17
19
  build(): Promise<Changeset>;
20
+ buildWithOptions_BETA?(options: ChangesetOptions): Promise<Changeset>;
18
21
  operation: WriteOperation;
19
22
  editedEnt?(): Promise<TEnt | null>;
20
23
  nodeType: string;
24
+ getInput(): Data;
25
+ orchestrator: BuilderOrchestrator;
21
26
  }
22
27
  export interface Executor extends Iterable<DataOperation>, Iterator<DataOperation> {
23
28
  placeholderID: ID;
24
29
  resolveValue(val: any): Ent | null;
30
+ builderOpChanged(builder: Builder<any>): boolean;
31
+ builder?: Builder<Ent>;
25
32
  execute(): Promise<void>;
26
33
  preFetch?(queryer: Queryer, context?: Context): Promise<void>;
27
34
  postFetch?(queryer: Queryer, context?: Context): Promise<void>;
@@ -34,7 +41,7 @@ export interface Changeset {
34
41
  changesets?: Changeset[];
35
42
  dependencies?: Map<ID, Builder<Ent>>;
36
43
  }
37
- export declare type TriggerReturn = void | Promise<Changeset | void | (Changeset | void)[]> | Promise<Changeset>[];
44
+ export type TriggerReturn = void | Promise<Changeset | void | (Changeset | void)[]> | Promise<Changeset>[];
38
45
  export interface Trigger<TEnt extends Ent<TViewer>, TBuilder extends Builder<TEnt, TViewer, TExistingEnt>, TViewer extends Viewer = Viewer, TInput extends Data = Data, TExistingEnt extends TMaybleNullableEnt<TEnt> = MaybeNull<TEnt>> {
39
46
  changeset(builder: TBuilder, input: TInput): TriggerReturn;
40
47
  }
@@ -42,21 +49,25 @@ export interface Observer<TEnt extends Ent<TViewer>, TBuilder extends Builder<TE
42
49
  observe(builder: TBuilder, input: TInput): void | Promise<void>;
43
50
  }
44
51
  export interface Validator<TEnt extends Ent<TViewer>, TBuilder extends Builder<TEnt, TViewer, TExistingEnt>, TViewer extends Viewer = Viewer, TInput extends Data = Data, TExistingEnt extends TMaybleNullableEnt<TEnt> = MaybeNull<TEnt>> {
45
- validate(builder: TBuilder, input: TInput): Promise<void> | void;
52
+ validate(builder: TBuilder, input: TInput): Promise<void | undefined | Error> | void | Error | undefined;
53
+ }
54
+ export interface ChangesetOptions {
55
+ conditionalBuilder: Builder<any, any>;
46
56
  }
47
57
  export interface Action<TEnt extends Ent<TViewer>, TBuilder extends Builder<TEnt, TViewer, TExistingEnt>, TViewer extends Viewer = Viewer, TInput extends Data = Data, TExistingEnt extends TMaybleNullableEnt<TEnt> = MaybeNull<TEnt>> {
48
58
  readonly viewer: Viewer;
49
59
  changeset(): Promise<Changeset>;
60
+ changesetWithOptions_BETA?(options: ChangesetOptions): Promise<Changeset>;
50
61
  builder: TBuilder;
51
62
  getPrivacyPolicy(): PrivacyPolicy<TEnt>;
52
- getTriggers?(): Trigger<TEnt, TBuilder, TViewer, TInput, TExistingEnt>[];
63
+ getTriggers?(): (Trigger<TEnt, TBuilder, TViewer, TInput, TExistingEnt> | Trigger<TEnt, TBuilder, TViewer, TInput, TExistingEnt>[])[];
53
64
  getObservers?(): Observer<TEnt, TBuilder, TViewer, TInput, TExistingEnt>[];
54
65
  getValidators?(): Validator<TEnt, TBuilder, TViewer, TInput, TExistingEnt>[];
55
66
  getInput(): TInput;
56
- transformWrite?: (stmt: UpdateOperation<TEnt>) => Promise<TransformedUpdateOperation<TEnt>> | TransformedUpdateOperation<TEnt> | null;
67
+ transformWrite?: (stmt: UpdateOperation<TEnt, TViewer>) => Promise<TransformedUpdateOperation<TEnt, TViewer>> | TransformedUpdateOperation<TEnt, TViewer> | null;
57
68
  valid(): Promise<boolean>;
58
69
  validX(): Promise<void>;
59
- viewerForEntLoad?(data: Data): TViewer | Promise<TViewer>;
70
+ viewerForEntLoad?(data: Data, context?: Context<TViewer>): TViewer | Promise<TViewer>;
60
71
  }
61
72
  export declare function saveBuilder<TEnt extends Ent<TViewer>, TViewer extends Viewer>(builder: Builder<TEnt, TViewer>): Promise<void>;
62
73
  export declare function saveBuilderX<TEnt extends Ent<TViewer>, TViewer extends Viewer>(builder: Builder<TEnt, TViewer>): Promise<void>;
@@ -66,4 +77,4 @@ interface Orchestrator {
66
77
  viewer: Viewer;
67
78
  }
68
79
  export declare function setEdgeTypeInGroup<T extends string>(orchestrator: Orchestrator, inputEnumValue: string, id1: ID, id2: ID, nodeType: string, m: Map<T, string>): Promise<void>;
69
- export {};
80
+ export declare function clearEdgeTypeInGroup<T extends string>(orchestrator: Orchestrator, id1: ID, id2: ID, m: Map<T, string>): Promise<void>;
package/action/action.js CHANGED
@@ -1,14 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.setEdgeTypeInGroup = exports.saveBuilderX = exports.saveBuilder = exports.WriteOperation = void 0;
3
+ exports.clearEdgeTypeInGroup = exports.setEdgeTypeInGroup = exports.saveBuilderX = exports.saveBuilder = exports.WriteOperation = void 0;
4
+ const base_1 = require("../core/base");
5
+ Object.defineProperty(exports, "WriteOperation", { enumerable: true, get: function () { return base_1.WriteOperation; } });
4
6
  const ent_1 = require("../core/ent");
5
7
  const logger_1 = require("../core/logger");
6
- var WriteOperation;
7
- (function (WriteOperation) {
8
- WriteOperation["Insert"] = "insert";
9
- WriteOperation["Edit"] = "edit";
10
- WriteOperation["Delete"] = "delete";
11
- })(WriteOperation = exports.WriteOperation || (exports.WriteOperation = {}));
12
8
  async function saveBuilder(builder) {
13
9
  await saveBuilderImpl(builder, false);
14
10
  }
@@ -88,3 +84,22 @@ async function setEdgeTypeInGroup(orchestrator, inputEnumValue, id1, id2, nodeTy
88
84
  await Promise.all(promises);
89
85
  }
90
86
  exports.setEdgeTypeInGroup = setEdgeTypeInGroup;
87
+ async function clearEdgeTypeInGroup(orchestrator, id1, id2, m) {
88
+ let promises = [];
89
+ for (const [_, edgeType] of m) {
90
+ promises.push((async () => {
91
+ let edge = await (0, ent_1.loadEdgeForID2)({
92
+ id1,
93
+ id2,
94
+ edgeType,
95
+ ctr: ent_1.AssocEdge,
96
+ context: orchestrator.viewer.context,
97
+ });
98
+ if (edge) {
99
+ orchestrator.removeOutboundEdge(id2, edgeType);
100
+ }
101
+ })());
102
+ }
103
+ await Promise.all(promises);
104
+ }
105
+ exports.clearEdgeTypeInGroup = clearEdgeTypeInGroup;
@@ -1,19 +1,23 @@
1
1
  import { ID, Ent, Viewer, Context, Data } from "../core/base";
2
- import { DataOperation } from "../core/ent";
3
2
  import { Changeset, Executor } from "../action/action";
4
3
  import { Builder } from "../action";
5
4
  import { OrchestratorOptions } from "./orchestrator";
6
5
  import { Queryer } from "../core/db";
6
+ import { DataOperation } from "./operations";
7
7
  export declare class ListBasedExecutor<T extends Ent> implements Executor {
8
8
  private viewer;
9
9
  placeholderID: ID;
10
10
  private operations;
11
11
  private options?;
12
+ private complexOptions?;
12
13
  private idx;
13
- constructor(viewer: Viewer, placeholderID: ID, operations: DataOperation<T>[], options?: OrchestratorOptions<T, Viewer<Ent<any> | null, ID | null>, Data, T | null> | undefined);
14
+ builder?: Builder<Ent> | undefined;
15
+ constructor(viewer: Viewer, placeholderID: ID, operations: DataOperation<T>[], options?: OrchestratorOptions<T, Data, Viewer<Ent<any> | null, ID | null>, T | null> | undefined, complexOptions?: ComplexExecutorOptions | undefined);
14
16
  private lastOp;
15
17
  private createdEnt;
18
+ private changedOps;
16
19
  resolveValue(val: ID): Ent | null;
20
+ builderOpChanged(builder: Builder<any>): boolean;
17
21
  [Symbol.iterator](): this;
18
22
  next(): IteratorResult<DataOperation<T>>;
19
23
  executeObservers(): Promise<void>;
@@ -21,22 +25,31 @@ export declare class ListBasedExecutor<T extends Ent> implements Executor {
21
25
  preFetch?(queryer: Queryer, context: Context): Promise<void>;
22
26
  postFetch?(queryer: Queryer, context: Context): Promise<void>;
23
27
  }
28
+ interface ComplexExecutorOptions {
29
+ conditionalOverride: boolean;
30
+ builder: Builder<any, any>;
31
+ }
24
32
  export declare class ComplexExecutor<T extends Ent> implements Executor {
25
33
  private viewer;
26
34
  placeholderID: ID;
35
+ private complexOptions?;
27
36
  private idx;
28
37
  private mapper;
29
38
  private lastOp;
30
39
  private allOperations;
31
40
  private executors;
32
- constructor(viewer: Viewer, placeholderID: ID, operations: DataOperation[], dependencies: Map<ID, Builder<T>>, changesets: Changeset[], options?: OrchestratorOptions<T, Viewer, Data>);
41
+ private changedOps;
42
+ builder?: Builder<Ent> | undefined;
43
+ constructor(viewer: Viewer, placeholderID: ID, operations: DataOperation[], dependencies: Map<ID, Builder<T>>, changesets: Changeset[], options?: OrchestratorOptions<T, Data, Viewer>, complexOptions?: ComplexExecutorOptions | undefined);
33
44
  [Symbol.iterator](): this;
34
45
  private handleCreatedEnt;
35
46
  next(): IteratorResult<DataOperation<Ent>>;
36
47
  resolveValue(val: ID): Ent | null;
48
+ builderOpChanged(builder: Builder<any>): boolean;
37
49
  executeObservers(): Promise<void>;
38
50
  execute(): Promise<void>;
39
51
  preFetch?(queryer: Queryer, context: Context): Promise<void>;
40
52
  postFetch?(queryer: Queryer, context: Context): Promise<void>;
41
53
  }
42
54
  export declare function executeOperations(executor: Executor, context?: Context, trackOps?: true): Promise<DataOperation<Ent<Viewer<Ent<any> | null, ID | null>>>[]>;
55
+ export {};
@@ -4,18 +4,23 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.executeOperations = exports.ComplexExecutor = exports.ListBasedExecutor = void 0;
7
- const graph_data_structure_1 = __importDefault(require("graph-data-structure"));
7
+ const graph_data_structure_1 = require("graph-data-structure");
8
+ const ent_1 = require("../core/ent");
8
9
  const db_1 = __importDefault(require("../core/db"));
9
10
  const logger_1 = require("../core/logger");
11
+ const operations_1 = require("./operations");
10
12
  // private to ent
11
13
  class ListBasedExecutor {
12
- constructor(viewer, placeholderID, operations, options) {
14
+ constructor(viewer, placeholderID, operations, options, complexOptions) {
13
15
  this.viewer = viewer;
14
16
  this.placeholderID = placeholderID;
15
17
  this.operations = operations;
16
18
  this.options = options;
19
+ this.complexOptions = complexOptions;
17
20
  this.idx = 0;
18
21
  this.createdEnt = null;
22
+ this.changedOps = new Map();
23
+ this.builder = options?.builder;
19
24
  }
20
25
  resolveValue(val) {
21
26
  if (val === this.placeholderID && val !== undefined) {
@@ -23,6 +28,10 @@ class ListBasedExecutor {
23
28
  }
24
29
  return null;
25
30
  }
31
+ builderOpChanged(builder) {
32
+ const v = this.changedOps.get(builder.placeholderID);
33
+ return v !== undefined && v !== builder.operation;
34
+ }
26
35
  [Symbol.iterator]() {
27
36
  return this;
28
37
  }
@@ -32,17 +41,19 @@ class ListBasedExecutor {
32
41
  if (createdEnt) {
33
42
  this.createdEnt = createdEnt;
34
43
  }
35
- const done = this.idx === this.operations.length;
36
- const op = this.operations[this.idx];
44
+ maybeFlagOpOperationAsChanged(this.lastOp, this.changedOps);
45
+ const done = this.idx >= this.operations.length;
46
+ const op = maybeChangeOp(this.operations[this.idx], this.complexOptions);
37
47
  this.idx++;
38
48
  this.lastOp = op;
39
- // reset since this could be called multiple times. not needed if we have getSortedOps or something like that
40
- if (done) {
41
- this.idx = 0;
49
+ if (done || op === undefined) {
50
+ return {
51
+ value: op,
52
+ done: true,
53
+ };
42
54
  }
43
55
  return {
44
56
  value: op,
45
- done: done,
46
57
  };
47
58
  }
48
59
  async executeObservers() {
@@ -52,7 +63,13 @@ class ListBasedExecutor {
52
63
  }
53
64
  const builder = this.options.builder;
54
65
  await Promise.all(action.getObservers().map(async (observer) => {
55
- await observer.observe(builder, action.getInput());
66
+ try {
67
+ await observer.observe(builder, action.getInput());
68
+ }
69
+ catch (err) {
70
+ // TODO we eventually want a global observer error handler so that this can be logged or whatever...
71
+ // TODO https://github.com/lolopinto/ent/issues/1429
72
+ }
56
73
  }));
57
74
  }
58
75
  async execute() {
@@ -84,21 +101,34 @@ function getCreatedEnt(viewer, op) {
84
101
  }
85
102
  return null;
86
103
  }
104
+ function maybeFlagOpOperationAsChanged(op, changedOps) {
105
+ if (!op || !op.updatedOperation) {
106
+ return;
107
+ }
108
+ const r = op.updatedOperation();
109
+ if (!r || r.builder.operation === r.operation) {
110
+ return;
111
+ }
112
+ changedOps.set(r.builder.placeholderID, r.operation);
113
+ }
87
114
  class ComplexExecutor {
88
- constructor(viewer, placeholderID, operations, dependencies, changesets, options) {
115
+ constructor(viewer, placeholderID, operations, dependencies, changesets, options, complexOptions) {
89
116
  this.viewer = viewer;
90
117
  this.placeholderID = placeholderID;
118
+ this.complexOptions = complexOptions;
91
119
  this.idx = 0;
92
120
  this.mapper = new Map();
93
121
  this.allOperations = [];
94
122
  this.executors = [];
95
- let graph = (0, graph_data_structure_1.default)();
123
+ this.changedOps = new Map();
124
+ this.builder = options?.builder;
125
+ let graph = (0, graph_data_structure_1.Graph)();
96
126
  const changesetMap = new Map();
97
127
  const impl = (c) => {
98
128
  changesetMap.set(c.placeholderID.toString(), c);
99
129
  graph.addNode(c.placeholderID.toString());
100
130
  if (c.dependencies) {
101
- for (let [key, builder] of c.dependencies) {
131
+ for (let [_, builder] of c.dependencies) {
102
132
  // dependency should go first...
103
133
  graph.addEdge(builder.placeholderID.toString(), c.placeholderID.toString(), 1);
104
134
  }
@@ -170,25 +200,24 @@ class ComplexExecutor {
170
200
  }
171
201
  const placeholderID = this.lastOp.placeholderID;
172
202
  if (!placeholderID) {
173
- console.error(`op ${this.lastOp} which implements getCreatedEnt doesn't have a placeholderID`);
174
- return;
203
+ throw new Error(`op ${this.lastOp} which implements getCreatedEnt doesn't have a placeholderID`);
175
204
  }
176
205
  this.mapper.set(placeholderID, createdEnt);
177
206
  }
178
207
  next() {
179
208
  this.handleCreatedEnt();
180
- const done = this.idx === this.allOperations.length;
181
- const op = this.allOperations[this.idx];
209
+ maybeFlagOpOperationAsChanged(this.lastOp, this.changedOps);
210
+ const done = this.idx >= this.allOperations.length;
211
+ const op = maybeChangeOp(this.allOperations[this.idx], this.complexOptions);
182
212
  this.idx++;
183
213
  this.lastOp = op;
184
- // reset since this could be called multiple times. not needed if we have getSortedOps or something like that
185
- if (done) {
186
- this.idx = 0;
214
+ if (done || op === undefined) {
215
+ return {
216
+ value: op,
217
+ done: true,
218
+ };
187
219
  }
188
- return {
189
- value: op,
190
- done: done,
191
- };
220
+ return { value: op };
192
221
  }
193
222
  resolveValue(val) {
194
223
  let ent = this.mapper.get(val);
@@ -203,8 +232,15 @@ class ComplexExecutor {
203
232
  }
204
233
  return null;
205
234
  }
235
+ builderOpChanged(builder) {
236
+ const v = this.changedOps.get(builder.placeholderID);
237
+ return v !== undefined && v !== builder.operation;
238
+ }
206
239
  async executeObservers() {
207
240
  await Promise.all(this.executors.map((executor) => {
241
+ if (executor.builder && this.builderOpChanged(executor.builder)) {
242
+ return null;
243
+ }
208
244
  if (!executor.executeObservers) {
209
245
  return null;
210
246
  }
@@ -247,6 +283,9 @@ async function executeOperations(executor, context, trackOps) {
247
283
  if (isSyncClient(client)) {
248
284
  client.runInTransaction(() => {
249
285
  for (const operation of executor) {
286
+ if (operation.shortCircuit && operation.shortCircuit(executor)) {
287
+ continue;
288
+ }
250
289
  if (trackOps) {
251
290
  operations.push(operation);
252
291
  }
@@ -258,8 +297,12 @@ async function executeOperations(executor, context, trackOps) {
258
297
  });
259
298
  }
260
299
  else {
300
+ (0, ent_1.logQuery)("BEGIN", []);
261
301
  await client.query("BEGIN");
262
302
  for (const operation of executor) {
303
+ if (operation.shortCircuit && operation.shortCircuit(executor)) {
304
+ continue;
305
+ }
263
306
  if (trackOps) {
264
307
  operations.push(operation);
265
308
  }
@@ -269,25 +312,43 @@ async function executeOperations(executor, context, trackOps) {
269
312
  }
270
313
  await operation.performWrite(client, context);
271
314
  }
315
+ (0, ent_1.logQuery)("COMMIT", []);
272
316
  await client.query("COMMIT");
273
317
  }
274
318
  if (executor.postFetch) {
275
319
  await executor.postFetch(client, context);
276
320
  }
277
- if (executor.executeObservers) {
278
- await executor.executeObservers();
279
- }
321
+ client.release();
280
322
  }
281
323
  catch (e) {
282
324
  if (!isSyncClient(client)) {
325
+ // TODO these changes break tests
326
+ (0, ent_1.logQuery)("ROLLBACK", []);
283
327
  await client.query("ROLLBACK");
284
328
  }
329
+ client.release(e);
285
330
  (0, logger_1.log)("error", e);
286
331
  throw e;
287
332
  }
288
- finally {
289
- client.release();
333
+ if (executor.executeObservers) {
334
+ try {
335
+ await executor.executeObservers();
336
+ }
337
+ catch (e) { }
290
338
  }
291
339
  return operations;
292
340
  }
293
341
  exports.executeOperations = executeOperations;
342
+ function maybeChangeOp(op, complexOptions) {
343
+ if (!op ||
344
+ !complexOptions?.conditionalOverride ||
345
+ op instanceof operations_1.ConditionalNodeOperation) {
346
+ return op;
347
+ }
348
+ if (op.createdEnt) {
349
+ return new operations_1.ConditionalNodeOperation(op, complexOptions.builder);
350
+ }
351
+ else {
352
+ return new operations_1.ConditionalOperation(op, complexOptions.builder);
353
+ }
354
+ }
@@ -1,11 +1,14 @@
1
+ import { Orchestrator } from "./orchestrator";
1
2
  import { Viewer, Ent, Data } from "../core/base";
2
3
  import { Action, WriteOperation, Builder, Trigger, Observer, Changeset, Validator } from "./action";
3
- export interface ActionOptions<T extends Ent, TData extends Data> {
4
- existingEnt?: T | null;
4
+ export interface ActionOptions<TEnt extends Ent<TViewer>, TViewer extends Viewer, TData extends Data, TExistingEnt extends TMaybleNullableEnt<TEnt> = MaybeNull<TEnt>> {
5
+ existingEnt: TExistingEnt;
5
6
  input?: TData;
6
7
  operation?: WriteOperation;
7
8
  }
8
- interface EntBuilder<TEnt extends Ent<TViewer>, TViewer extends Viewer, TInput extends Data> extends Builder<TEnt, TViewer> {
9
+ type MaybeNull<T extends Ent> = T | null;
10
+ type TMaybleNullableEnt<T extends Ent> = T | MaybeNull<T>;
11
+ export interface EntBuilder<TEnt extends Ent<TViewer>, TViewer extends Viewer, TInput extends Data, TExistingEnt extends TMaybleNullableEnt<TEnt> = MaybeNull<TEnt>> extends Builder<TEnt, TViewer, TExistingEnt> {
9
12
  valid(): Promise<boolean>;
10
13
  validX(): Promise<void>;
11
14
  save(): Promise<void>;
@@ -13,19 +16,23 @@ interface EntBuilder<TEnt extends Ent<TViewer>, TViewer extends Viewer, TInput e
13
16
  editedEnt(): Promise<TEnt | null>;
14
17
  editedEntX(): Promise<TEnt>;
15
18
  getInput(): TInput;
19
+ orchestrator: Orchestrator<TEnt, TInput, TViewer, TExistingEnt>;
16
20
  }
17
- export declare class BaseAction<TEnt extends Ent<TViewer>, TViewer extends Viewer, TInput extends Data> implements Action<TEnt, EntBuilder<TEnt, TViewer, TInput>, TViewer, TInput> {
21
+ export declare class BaseAction<TEnt extends Ent<TViewer>, TViewer extends Viewer, TInput extends Data, TExistingEnt extends TMaybleNullableEnt<TEnt> = MaybeNull<TEnt>> implements Action<TEnt, EntBuilder<TEnt, TViewer, TInput, TExistingEnt>, TViewer, TInput, TExistingEnt> {
18
22
  viewer: TViewer;
19
- builderCtr: BuilderConstructor<TEnt, TViewer, TInput>;
20
- builder: EntBuilder<TEnt, TViewer, TInput>;
23
+ builderCtr: BuilderConstructor<TEnt, TViewer, TInput, TExistingEnt>;
24
+ builder: EntBuilder<TEnt, TViewer, TInput, TExistingEnt>;
21
25
  private input;
22
26
  getPrivacyPolicy(): import("../core/base").PrivacyPolicy<Ent<Viewer<Ent<any> | null, import("../core/base").ID | null>>, Viewer<Ent<any> | null, import("../core/base").ID | null>>;
23
- getTriggers(): Trigger<TEnt, EntBuilder<TEnt, TViewer, TInput>, TViewer, TInput>[];
24
- getObservers(): Observer<TEnt, EntBuilder<TEnt, TViewer, TInput>, TViewer, TInput>[];
25
- getValidators(): Validator<TEnt, EntBuilder<TEnt, TViewer, TInput>, TViewer, TInput>[];
26
- constructor(viewer: TViewer, builderCtr: BuilderConstructor<TEnt, TViewer, TInput>, options?: ActionOptions<TEnt, TInput> | null);
27
- static createBuilder<TEnt extends Ent<TViewer>, TViewer extends Viewer, TInput extends Data>(viewer: Viewer, builderCtr: BuilderConstructor<TEnt, TViewer, TInput>, options?: ActionOptions<TEnt, TInput> | null): Builder<TEnt>;
28
- static bulkAction<TEnt extends Ent<TViewer>, TViewer extends Viewer, TInput extends Data>(ent: TEnt, builderCtr: BuilderConstructor<TEnt, TViewer, TInput>, ...actions: Action<Ent, Builder<Ent, any>>[]): BaseAction<TEnt, TViewer, TInput>;
27
+ getTriggers(): Trigger<TEnt, EntBuilder<TEnt, TViewer, TInput, TExistingEnt>, TViewer, TInput, TExistingEnt>[];
28
+ getObservers(): Observer<TEnt, EntBuilder<TEnt, TViewer, TInput, TExistingEnt>, TViewer, TInput, TExistingEnt>[];
29
+ getValidators(): Validator<TEnt, EntBuilder<TEnt, TViewer, TInput, TExistingEnt>, TViewer, TInput, TExistingEnt>[];
30
+ constructor(viewer: TViewer, builderCtr: BuilderConstructor<TEnt, TViewer, TInput, TExistingEnt>, options: ActionOptions<TEnt, TViewer, TInput, TExistingEnt>);
31
+ static createBuilder<TEnt extends Ent<TViewer>, TViewer extends Viewer, TInput extends Data, TExistingEnt extends TMaybleNullableEnt<TEnt> = MaybeNull<TEnt>>(viewer: Viewer, builderCtr: BuilderConstructor<TEnt, TViewer, TInput, TExistingEnt>, options: ActionOptions<TEnt, TViewer, TInput, TExistingEnt>): Builder<TEnt>;
32
+ /**
33
+ * @deprecated use Transaction
34
+ */
35
+ static bulkAction<TEnt extends Ent<TViewer>, TViewer extends Viewer, TInput extends Data>(ent: TEnt, builderCtr: BuilderConstructor<TEnt, TViewer, TInput, TEnt>, ...actions: Action<Ent, Builder<Ent, any>>[]): BaseAction<TEnt, TViewer, TInput, TEnt>;
29
36
  changeset(): Promise<Changeset>;
30
37
  valid(): Promise<boolean>;
31
38
  validX(): Promise<void>;
@@ -33,9 +40,11 @@ export declare class BaseAction<TEnt extends Ent<TViewer>, TViewer extends Viewe
33
40
  saveX(): Promise<TEnt>;
34
41
  getInput(): TInput;
35
42
  }
36
- interface BuilderConstructor<TEnt extends Ent<TViewer>, TViewer extends Viewer, TInput extends Data> {
37
- new (viewer: TViewer, operation: WriteOperation, action: Action<TEnt, EntBuilder<TEnt, TViewer, TInput>, TViewer, TInput>, existingEnt: TEnt | null): EntBuilder<TEnt, TViewer, TInput>;
43
+ export interface BuilderConstructor<TEnt extends Ent<TViewer>, TViewer extends Viewer, TInput extends Data, TExistingEnt extends TMaybleNullableEnt<TEnt> = MaybeNull<TEnt>> {
44
+ new (viewer: TViewer, operation: WriteOperation, action: Action<TEnt, any, TViewer, TInput, TExistingEnt>, existingEnt: TExistingEnt): EntBuilder<TEnt, TViewer, TInput, TExistingEnt>;
38
45
  }
39
- export declare function updateRawObject<TEnt extends Ent<TViewer>, TViewer extends Viewer, TInput extends Data>(viewer: Viewer, builderCtr: BuilderConstructor<TEnt, TViewer, TInput>, existingEnt: TEnt, input: TInput): Promise<TEnt>;
40
- export declare function getSimpleEditAction<TEnt extends Ent<TViewer>, TViewer extends Viewer, TInput extends Data>(viewer: TViewer, builderCtr: BuilderConstructor<TEnt, TViewer, TInput>, existingEnt: TEnt, input: TInput): Action<TEnt, Builder<TEnt, TViewer>, TViewer, TInput>;
46
+ export declare function updateRawObject<TEnt extends Ent<TViewer>, TViewer extends Viewer, TInput extends Data>(viewer: TViewer, builderCtr: BuilderConstructor<TEnt, TViewer, TInput, TEnt>, existingEnt: TEnt, input: TInput): Promise<TEnt>;
47
+ export declare function getSimpleEditAction<TEnt extends Ent<TViewer>, TViewer extends Viewer, TInput extends Data>(viewer: TViewer, builderCtr: BuilderConstructor<TEnt, TViewer, TInput, TEnt>, existingEnt: TEnt, input: TInput): BaseAction<TEnt, TViewer, TInput, TEnt>;
48
+ export declare function getSimpleDeleteAction<TEnt extends Ent<TViewer>, TViewer extends Viewer, TInput extends Data>(viewer: TViewer, builderCtr: BuilderConstructor<TEnt, TViewer, TInput, TEnt>, existingEnt: TEnt, input: TInput): BaseAction<TEnt, TViewer, TInput, TEnt>;
49
+ export declare function getSimpleInsertAction<TEnt extends Ent<TViewer>, TViewer extends Viewer, TInput extends Data>(viewer: TViewer, builderCtr: BuilderConstructor<TEnt, TViewer, TInput, null>, input: TInput): BaseAction<TEnt, TViewer, TInput, null>;
41
50
  export {};
@@ -1,9 +1,21 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getSimpleEditAction = exports.updateRawObject = exports.BaseAction = void 0;
3
+ exports.getSimpleInsertAction = exports.getSimpleDeleteAction = exports.getSimpleEditAction = exports.updateRawObject = exports.BaseAction = void 0;
4
4
  const privacy_1 = require("../core/privacy");
5
5
  const action_1 = require("./action");
6
6
  class BaseAction {
7
+ getPrivacyPolicy() {
8
+ return privacy_1.AlwaysAllowPrivacyPolicy;
9
+ }
10
+ getTriggers() {
11
+ return [];
12
+ }
13
+ getObservers() {
14
+ return [];
15
+ }
16
+ getValidators() {
17
+ return [];
18
+ }
7
19
  constructor(viewer, builderCtr, options) {
8
20
  this.viewer = viewer;
9
21
  this.builderCtr = builderCtr;
@@ -17,19 +29,7 @@ class BaseAction {
17
29
  }
18
30
  }
19
31
  this.input = options?.input || {};
20
- this.builder = new builderCtr(viewer, operation, this, options?.existingEnt || null);
21
- }
22
- getPrivacyPolicy() {
23
- return privacy_1.AlwaysAllowPrivacyPolicy;
24
- }
25
- getTriggers() {
26
- return [];
27
- }
28
- getObservers() {
29
- return [];
30
- }
31
- getValidators() {
32
- return [];
32
+ this.builder = new builderCtr(viewer, operation, this, options.existingEnt);
33
33
  }
34
34
  static createBuilder(viewer, builderCtr, options) {
35
35
  let action = new BaseAction(viewer, builderCtr, options);
@@ -37,6 +37,9 @@ class BaseAction {
37
37
  }
38
38
  // perform a bulk action in a transaction rooted on ent T
39
39
  // it ends up creating triggers and having all the given actions performed in a transaction
40
+ /**
41
+ * @deprecated use Transaction
42
+ */
40
43
  static bulkAction(ent, builderCtr, ...actions) {
41
44
  let action = new BaseAction(ent.viewer, builderCtr, {
42
45
  existingEnt: ent,
@@ -85,6 +88,7 @@ async function updateRawObject(viewer, builderCtr, existingEnt, input) {
85
88
  return action.saveX();
86
89
  }
87
90
  exports.updateRawObject = updateRawObject;
91
+ // TODO need to fix types for all these
88
92
  // creates an action which has no privacy, triggers, observers etc
89
93
  // does do field validation
90
94
  // useful to batch a bunch of writes together with BaseAction.bulkAction
@@ -97,3 +101,19 @@ function getSimpleEditAction(viewer, builderCtr, existingEnt, input) {
97
101
  });
98
102
  }
99
103
  exports.getSimpleEditAction = getSimpleEditAction;
104
+ function getSimpleDeleteAction(viewer, builderCtr, existingEnt, input) {
105
+ return new BaseAction(viewer, builderCtr, {
106
+ existingEnt: existingEnt,
107
+ operation: action_1.WriteOperation.Delete,
108
+ input,
109
+ });
110
+ }
111
+ exports.getSimpleDeleteAction = getSimpleDeleteAction;
112
+ function getSimpleInsertAction(viewer, builderCtr, input) {
113
+ return new BaseAction(viewer, builderCtr, {
114
+ operation: action_1.WriteOperation.Insert,
115
+ input,
116
+ existingEnt: null,
117
+ });
118
+ }
119
+ exports.getSimpleInsertAction = getSimpleInsertAction;
package/action/index.d.ts CHANGED
@@ -1,3 +1,6 @@
1
- export { WriteOperation, Builder, Changeset, Trigger, Observer, Validator, Action, saveBuilder, saveBuilderX, setEdgeTypeInGroup, TriggerReturn, } from "./action";
1
+ export { WriteOperation, Builder, Changeset, Trigger, Observer, Validator, Action, saveBuilder, saveBuilderX, setEdgeTypeInGroup, TriggerReturn, ChangesetOptions, } from "./action";
2
2
  export { OrchestratorOptions, Orchestrator, EntChangeset, EdgeInputData, } from "./orchestrator";
3
3
  export { DenyIfBuilder, AllowIfBuilder } from "./privacy";
4
+ export { RelativeFieldValue, RelativeNumberValue, NumberOps, convertRelativeInput, maybeConvertRelativeInputPlusExpressions, } from "./relative_value";
5
+ export { Transaction } from "./transaction";
6
+ export { AssocEdgeOptions } from "./operations";
package/action/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.AllowIfBuilder = exports.DenyIfBuilder = exports.EntChangeset = exports.Orchestrator = exports.setEdgeTypeInGroup = exports.saveBuilderX = exports.saveBuilder = exports.WriteOperation = void 0;
3
+ exports.Transaction = exports.maybeConvertRelativeInputPlusExpressions = exports.convertRelativeInput = exports.NumberOps = exports.AllowIfBuilder = exports.DenyIfBuilder = exports.EntChangeset = exports.Orchestrator = exports.setEdgeTypeInGroup = exports.saveBuilderX = exports.saveBuilder = exports.WriteOperation = void 0;
4
4
  var action_1 = require("./action");
5
5
  Object.defineProperty(exports, "WriteOperation", { enumerable: true, get: function () { return action_1.WriteOperation; } });
6
6
  Object.defineProperty(exports, "saveBuilder", { enumerable: true, get: function () { return action_1.saveBuilder; } });
@@ -12,3 +12,9 @@ Object.defineProperty(exports, "EntChangeset", { enumerable: true, get: function
12
12
  var privacy_1 = require("./privacy");
13
13
  Object.defineProperty(exports, "DenyIfBuilder", { enumerable: true, get: function () { return privacy_1.DenyIfBuilder; } });
14
14
  Object.defineProperty(exports, "AllowIfBuilder", { enumerable: true, get: function () { return privacy_1.AllowIfBuilder; } });
15
+ var relative_value_1 = require("./relative_value");
16
+ Object.defineProperty(exports, "NumberOps", { enumerable: true, get: function () { return relative_value_1.NumberOps; } });
17
+ Object.defineProperty(exports, "convertRelativeInput", { enumerable: true, get: function () { return relative_value_1.convertRelativeInput; } });
18
+ Object.defineProperty(exports, "maybeConvertRelativeInputPlusExpressions", { enumerable: true, get: function () { return relative_value_1.maybeConvertRelativeInputPlusExpressions; } });
19
+ var transaction_1 = require("./transaction");
20
+ Object.defineProperty(exports, "Transaction", { enumerable: true, get: function () { return transaction_1.Transaction; } });