nesoi 3.0.12 → 3.0.14

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 (56) hide show
  1. package/lib/compiler/apps/monolyth/stages/2_build_typescript_stage.js +5 -2
  2. package/lib/compiler/apps/monolyth/stages/3_copy_types_stage.js +2 -2
  3. package/lib/compiler/apps/monolyth/stages/4_dump_modules_stage.js +2 -2
  4. package/lib/compiler/apps/monolyth/stages/7_dump_package_json_stage.js +4 -1
  5. package/lib/compiler/compiler.d.ts +2 -0
  6. package/lib/compiler/compiler.js +10 -38
  7. package/lib/compiler/elements/cached.element.d.ts +11 -0
  8. package/lib/compiler/elements/cached.element.js +18 -0
  9. package/lib/compiler/elements/element.d.ts +3 -1
  10. package/lib/compiler/elements/element.js +3 -1
  11. package/lib/compiler/elements/externals.element.d.ts +1 -1
  12. package/lib/compiler/elements/externals.element.js +2 -35
  13. package/lib/compiler/module.d.ts +3 -2
  14. package/lib/compiler/module.js +9 -2
  15. package/lib/compiler/progressive.d.ts +71 -0
  16. package/lib/compiler/progressive.js +164 -0
  17. package/lib/compiler/stages/1_scan_stage.js +5 -2
  18. package/lib/compiler/stages/2_treeshake_stage.js +7 -1
  19. package/lib/compiler/stages/3_extract_ts_stage.js +9 -0
  20. package/lib/compiler/stages/4_build_schemas_stage.js +10 -1
  21. package/lib/compiler/stages/5_inject_ts_stage.js +3 -0
  22. package/lib/compiler/stages/6_build_elements_stage.js +3 -0
  23. package/lib/compiler/stages/7_dump_stage.d.ts +4 -1
  24. package/lib/compiler/stages/7_dump_stage.js +108 -44
  25. package/lib/compiler/stages/8_diagnose_stage.js +3 -0
  26. package/lib/compiler/treeshake.d.ts +5 -2
  27. package/lib/compiler/treeshake.js +41 -8
  28. package/lib/compiler/typescript/bridge/inject.js +2 -0
  29. package/lib/compiler/typescript/transformers/app_inject.transformer.js +1 -1
  30. package/lib/elements/blocks/resource/resource.js +1 -1
  31. package/lib/elements/entities/bucket/bucket.d.ts +3 -1
  32. package/lib/elements/entities/bucket/bucket.js +18 -6
  33. package/lib/engine/apps/app.config.d.ts +11 -9
  34. package/lib/engine/apps/app.config.js +1 -2
  35. package/lib/engine/apps/app.js +2 -2
  36. package/lib/engine/data/trash.d.ts +13 -10
  37. package/lib/engine/data/trash.js +33 -0
  38. package/lib/engine/dependency.d.ts +6 -0
  39. package/lib/engine/dependency.js +1 -0
  40. package/lib/engine/module.d.ts +4 -2
  41. package/lib/engine/module.js +8 -3
  42. package/lib/engine/space.d.ts +1 -1
  43. package/lib/engine/space.js +14 -5
  44. package/lib/engine/transaction/nodes/bucket.trx_node.d.ts +5 -1
  45. package/lib/engine/transaction/nodes/bucket.trx_node.js +9 -2
  46. package/lib/engine/transaction/nodes/bucket_query.trx_node.d.ts +3 -3
  47. package/lib/engine/transaction/nodes/bucket_query.trx_node.js +2 -2
  48. package/lib/engine/transaction/trx_engine.d.ts +1 -1
  49. package/lib/engine/transaction/trx_node.d.ts +1 -1
  50. package/lib/engine/transaction/trx_node.js +3 -1
  51. package/lib/engine/tree.d.ts +8 -1
  52. package/lib/engine/tree.js +45 -25
  53. package/lib/engine/util/hash.d.ts +2 -1
  54. package/lib/engine/util/hash.js +10 -1
  55. package/package.json +1 -1
  56. package/tsconfig.build.tsbuildinfo +1 -1
@@ -1,14 +1,17 @@
1
- import { NesoiDatetime } from './datetime';
1
+ import { NesoiObj } from './obj';
2
+ import { AnyTrxNode } from '../transaction/trx_node';
3
+ import { $Bucket } from "../../elements/entities/bucket/bucket.schema";
4
+ import { AnyModule } from '../module';
2
5
  export type TrashObj = {
3
6
  id: number;
7
+ module: string;
4
8
  bucket: string;
5
- original_id: number | string;
6
- data: Record<string, any>;
7
- adapter: {
8
- name: string;
9
- [x: string]: any;
10
- };
11
- trx: Record<string, any>;
12
- deleted_by?: number | string;
13
- deleted_at: NesoiDatetime;
9
+ object_id: string;
10
+ object: Record<string, any>;
11
+ delete_trx_id: string;
14
12
  };
13
+ export declare const $TrashBucket: $Bucket;
14
+ export declare class Trash {
15
+ static add<Obj extends NesoiObj>(trx: AnyTrxNode, module: AnyModule, bucket: string, object: Obj): Promise<void>;
16
+ static addMany<Obj extends NesoiObj>(trx: AnyTrxNode, module: AnyModule, bucket: string, objects: Obj[]): Promise<void>;
17
+ }
@@ -1,2 +1,35 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Trash = exports.$TrashBucket = void 0;
4
+ const bucket_schema_1 = require("../../elements/entities/bucket/bucket.schema");
5
+ const bucket_model_schema_1 = require("../../elements/entities/bucket/model/bucket_model.schema");
6
+ const bucket_graph_schema_1 = require("../../elements/entities/bucket/graph/bucket_graph.schema");
7
+ exports.$TrashBucket = new bucket_schema_1.$Bucket('__trash__', 'trash', 'Trash', new bucket_model_schema_1.$BucketModel({
8
+ id: new bucket_model_schema_1.$BucketModelField('id', 'id', 'int', 'id', false, true),
9
+ module: new bucket_model_schema_1.$BucketModelField('module', 'module', 'string', 'Module Name', false, true),
10
+ bucket: new bucket_model_schema_1.$BucketModelField('bucket', 'bucket', 'string', 'Bucket Name', false, true),
11
+ object_id: new bucket_model_schema_1.$BucketModelField('object_id', 'object_id', 'int', 'Object ID', false, true),
12
+ object: new bucket_model_schema_1.$BucketModelField('object', 'object', 'dict', 'Object', false, true, undefined, undefined, {
13
+ __dict: new bucket_model_schema_1.$BucketModelField('', '', 'unknown', '', false, true, undefined, undefined)
14
+ }),
15
+ delete_trx_id: new bucket_model_schema_1.$BucketModelField('delete_trx_id', 'delete_trx_id', 'int', 'ID of Delete Transaction', false, true),
16
+ }), new bucket_graph_schema_1.$BucketGraph(), {});
17
+ class Trash {
18
+ static async add(trx, module, bucket, object) {
19
+ if (!module.trash)
20
+ return;
21
+ await module.trash.create(trx, {
22
+ module: module.name,
23
+ bucket,
24
+ object_id: object.id,
25
+ object,
26
+ delete_trx_id: trx.globalId
27
+ });
28
+ }
29
+ static async addMany(trx, module, bucket, objects) {
30
+ for (const object of objects) {
31
+ await this.add(trx, module, bucket, object);
32
+ }
33
+ }
34
+ }
35
+ exports.Trash = Trash;
@@ -96,6 +96,9 @@ export declare class BuilderNode {
96
96
  filepath: string | string[];
97
97
  dependencies: $Dependency[];
98
98
  builder: AnyBuilder;
99
+ progressive?: {
100
+ schema: AnyElementSchema;
101
+ };
99
102
  constructor($: {
100
103
  module: string;
101
104
  type: BuilderType;
@@ -104,6 +107,9 @@ export declare class BuilderNode {
104
107
  filepath: string | string[];
105
108
  dependencies: $Dependency[];
106
109
  builder: AnyBuilder;
110
+ progressive?: {
111
+ schema: AnyElementSchema;
112
+ };
107
113
  });
108
114
  }
109
115
  /**
@@ -156,6 +156,7 @@ class BuilderNode {
156
156
  this.filepath = $.filepath;
157
157
  this.dependencies = $.dependencies;
158
158
  this.builder = $.builder;
159
+ this.progressive = $.progressive;
159
160
  }
160
161
  }
161
162
  exports.BuilderNode = BuilderNode;
@@ -11,7 +11,7 @@ import { $Message } from "../elements/entities/message/message.schema";
11
11
  import { Resource } from "../elements/blocks/resource/resource";
12
12
  import { Queue } from "../elements/blocks/queue/queue";
13
13
  import { Controller } from "../elements/edge/controller/controller";
14
- import { Bucket } from "../elements/entities/bucket/bucket";
14
+ import { AnyBucket, Bucket } from "../elements/entities/bucket/bucket";
15
15
  import { $Constants } from "../elements/entities/constants/constants.schema";
16
16
  import { ConstantsBuilder } from "../elements/entities/constants/constants.builder";
17
17
  import { AnyControllerBuilder } from "../elements/edge/controller/controller.builder";
@@ -63,6 +63,7 @@ export type VirtualModuleDef = {
63
63
  */
64
64
  export declare class Module<S extends $Space, $ extends $Module> {
65
65
  name: string;
66
+ subdir: string[];
66
67
  schema: $;
67
68
  buckets: { [B in keyof $["buckets"]]: Bucket<$, $["buckets"][B]>; };
68
69
  messages: { [B in keyof $["messages"]]: MessageParser<$["messages"][B]>; };
@@ -71,6 +72,7 @@ export declare class Module<S extends $Space, $ extends $Module> {
71
72
  machines: { [B in keyof $["machines"]]: Machine<S, $, $["machines"][B]>; };
72
73
  queues: { [B in keyof $["queues"]]: Queue<$, $["queues"][B]>; };
73
74
  controllers: { [B in keyof $["controllers"]]: Controller<S, $, $["controllers"][B]>; };
75
+ trash?: AnyBucket;
74
76
  /**
75
77
  * Daemon which is running the current module.
76
78
  * This is `undefined` when the _Module_ is created for compiling.
@@ -100,7 +102,7 @@ export declare class Module<S extends $Space, $ extends $Module> {
100
102
  dirpath: string;
101
103
  } | {
102
104
  builders: AnyBuilder[];
103
- });
105
+ }, subdir?: string[]);
104
106
  /**
105
107
  * Log the module elements
106
108
  */
@@ -59,6 +59,7 @@ const app_1 = require("./apps/app");
59
59
  const queue_builder_1 = require("../elements/blocks/queue/queue.builder");
60
60
  const nql_engine_1 = require("../elements/entities/bucket/query/nql_engine");
61
61
  const daemon_1 = require("./daemon");
62
+ const trash_1 = require("./data/trash");
62
63
  /**
63
64
  * A `Module` is an isolated named collection of _Elements_.
64
65
  *
@@ -78,8 +79,9 @@ class Module {
78
79
  * @param name A module name
79
80
  * @param boot The boot source for this module
80
81
  */
81
- constructor(name, boot) {
82
+ constructor(name, boot, subdir = []) {
82
83
  this.name = name;
84
+ this.subdir = subdir;
83
85
  this.schema = {
84
86
  constants: new constants_schema_1.$Constants(this.name),
85
87
  externals: new externals_schema_1.$Externals(this.name),
@@ -334,7 +336,7 @@ class Module {
334
336
  const config = info.config;
335
337
  Object.entries(this.schema.buckets).forEach(([name, schema]) => {
336
338
  const bucketConfig = config.buckets?.[this.name]?.[name];
337
- this.buckets[name] = new bucket_1.Bucket(schema, bucketConfig, services);
339
+ this.buckets[name] = new bucket_1.Bucket(this, schema, bucketConfig, services);
338
340
  });
339
341
  Object.entries(this.schema.messages).forEach(([name, schema]) => {
340
342
  this.messages[name] = new message_parser_1.MessageParser(schema);
@@ -356,6 +358,9 @@ class Module {
356
358
  this.queues[name] = new queue_1.Queue(this, schema);
357
359
  });
358
360
  this.nql = new nql_engine_1.NQL_Engine(this);
361
+ if (config.trash?.[this.name]) {
362
+ this.trash = new bucket_1.Bucket(this, trash_1.$TrashBucket, config.trash[this.name], services);
363
+ }
359
364
  }
360
365
  // Destroy
361
366
  /**
@@ -417,7 +422,7 @@ class Module {
417
422
  virtualModule.inject(def.schemas);
418
423
  }
419
424
  // Build schemas
420
- await virtualModule.start({ config: {} }, {});
425
+ await virtualModule.start({ _config: {} }, {});
421
426
  // Inject externals
422
427
  if (def.externals) {
423
428
  const modules = {};
@@ -203,6 +203,6 @@ export declare class Space<$ extends $Space> {
203
203
  * @param space A `Space` instance
204
204
  * @param buildFn A callback to run for each module directory
205
205
  */
206
- static scan(space: Space<any>, buildFn: (name: string, path: string) => void): void;
206
+ static scan(space: Space<any>, buildFn: (name: string, path: string, subdir: string[]) => void): void;
207
207
  }
208
208
  export type AnySpace = Space<$Space>;
@@ -296,11 +296,20 @@ class Space {
296
296
  if (!fs.existsSync(modulesPath)) {
297
297
  throw error_1.CompilerError.NoModulesFolder();
298
298
  }
299
- const dirs = fs.readdirSync(modulesPath, { withFileTypes: true })
300
- .filter(node => node.isDirectory());
301
- for (const dir of dirs) {
302
- buildFn(dir.name, path.join(modulesPath, dir.name));
303
- }
299
+ const perform = (dirpath, subdir) => {
300
+ const dirs = fs.readdirSync(dirpath, { withFileTypes: true })
301
+ .filter(node => node.isDirectory());
302
+ for (const dir of dirs) {
303
+ const modulePath = path.join(dirpath, dir.name);
304
+ if (fs.existsSync(path.join(modulePath, '.modules'))) {
305
+ perform(modulePath, [...subdir, dir.name]);
306
+ }
307
+ else {
308
+ buildFn(dir.name, modulePath, subdir);
309
+ }
310
+ }
311
+ };
312
+ perform(modulesPath, []);
304
313
  }
305
314
  }
306
315
  exports.Space = Space;
@@ -54,7 +54,11 @@ export declare class BucketTrxNode<M extends $Module, $ extends $Bucket> {
54
54
  /**
55
55
  * Returns a list containing the results of the query.
56
56
  */
57
- query<V extends ViewName<$> = 'default'>(query: NQL_Query<M, $>, view?: V): BucketQueryTrxNode<M, $, V>;
57
+ query(query: NQL_Query<M, $>): BucketQueryTrxNode<M, $>;
58
+ /**
59
+ * Returns a list containing the results of the query built with a view.
60
+ */
61
+ viewQuery<V extends ViewName<$> = 'default'>(query: NQL_Query<M, $>, view?: V): BucketQueryTrxNode<M, $, V>;
58
62
  /**
59
63
  * Returns one or more objects referenced by the graph link,
60
64
  * or `undefined` if the graph link doesn't resolve.
@@ -109,9 +109,16 @@ class BucketTrxNode {
109
109
  /**
110
110
  * Returns a list containing the results of the query.
111
111
  */
112
- query(query, view = 'default') {
112
+ query(query) {
113
113
  const trx = trx_node_1.TrxNode.makeChildNode(this.parentTrx, this.bucket.schema.module, 'bucket', this.bucket.schema.name);
114
- return new bucket_query_trx_node_1.BucketQueryTrxNode(trx, this.bucket, query, view, this.enableTenancy);
114
+ return new bucket_query_trx_node_1.BucketQueryTrxNode(trx, this.bucket, query, this.enableTenancy);
115
+ }
116
+ /**
117
+ * Returns a list containing the results of the query built with a view.
118
+ */
119
+ viewQuery(query, view = 'default') {
120
+ const trx = trx_node_1.TrxNode.makeChildNode(this.parentTrx, this.bucket.schema.module, 'bucket', this.bucket.schema.name);
121
+ return new bucket_query_trx_node_1.BucketQueryTrxNode(trx, this.bucket, query, this.enableTenancy, view);
115
122
  }
116
123
  /*
117
124
  Graph
@@ -8,13 +8,13 @@ import { NQL_Result } from "../../../elements/entities/bucket/query/nql_engine";
8
8
  * @category Engine
9
9
  * @subcategory Transaction
10
10
  */
11
- export declare class BucketQueryTrxNode<M extends $Module, B extends $Bucket, V extends ViewName<B>, Obj = ViewObj<B, V>> {
11
+ export declare class BucketQueryTrxNode<M extends $Module, B extends $Bucket, V extends ViewName<B> | undefined = undefined, Obj = V extends string ? ViewObj<B, V> : B['#data']> {
12
12
  private trx;
13
13
  private bucket;
14
14
  private query;
15
- private view;
16
15
  private enableTenancy;
17
- constructor(trx: TrxNode<any, M, any>, bucket: Bucket<M, B>, query: NQL_AnyQuery, view: V, enableTenancy: boolean);
16
+ private view?;
17
+ constructor(trx: TrxNode<any, M, any>, bucket: Bucket<M, B>, query: NQL_AnyQuery, enableTenancy: boolean, view?: V | undefined);
18
18
  merge($: NQL_Query<M, B>): void;
19
19
  first(): Promise<Obj | undefined>;
20
20
  firstOrFail(): Promise<Obj>;
@@ -8,12 +8,12 @@ const error_1 = require("../../data/error");
8
8
  * @subcategory Transaction
9
9
  */
10
10
  class BucketQueryTrxNode {
11
- constructor(trx, bucket, query, view, enableTenancy) {
11
+ constructor(trx, bucket, query, enableTenancy, view) {
12
12
  this.trx = trx;
13
13
  this.bucket = bucket;
14
14
  this.query = query;
15
- this.view = view;
16
15
  this.enableTenancy = enableTenancy;
16
+ this.view = view;
17
17
  }
18
18
  merge($) {
19
19
  const and = $['#and'];
@@ -5,7 +5,7 @@ import { TrxNode, TrxNodeStatus } from './trx_node';
5
5
  import { AnyAuthnProviders, AuthnRequest } from '../auth/authn';
6
6
  import { TrxEngineConfig } from './trx_engine.config';
7
7
  import { IService } from '../apps/service';
8
- export type TrxEngineOrigin = `app:${string}`;
8
+ export type TrxEngineOrigin = `app:${string}` | `plugin:${string}`;
9
9
  /**
10
10
  * @category Engine
11
11
  * @subcategory Transaction
@@ -59,7 +59,7 @@ export declare class TrxNode<Space extends $Space, M extends $Module, Authn exte
59
59
  machine<Name extends keyof M['machines'], Machine extends M['machines'][Name]>(name: Name): MachineTrxNode<M, Machine>;
60
60
  queue<Name extends keyof M['queues'], Queue extends M['queues'][Name]>(name: Name): QueueTrxNode<M, Queue>;
61
61
  authenticate(authnRequest: AuthnRequest<keyof Authn>): Promise<TrxNode<$Space, $Module, Authn>>;
62
- token<U extends keyof Authn & keyof M['#authn']>(provider: U): M['#authn'][U];
62
+ token<U extends keyof Authn & keyof M['#authn']>(provider: U): string;
63
63
  user<U extends keyof Authn & keyof M['#authn']>(provider: U): M['#authn'][U];
64
64
  virtual<T>(def: VirtualModuleDef, fn: ($: AnyTrxNode) => T | Promise<T>): Promise<T>;
65
65
  status(): TrxNodeStatus;
@@ -55,7 +55,9 @@ class TrxNode {
55
55
  error.message = i18n_1.i18n.error(error, node.trx.root.module.daemon);
56
56
  }
57
57
  else {
58
- error = new error_1.NesoiError.BaseError('UnknownError', error.message);
58
+ const _e = error;
59
+ error = new error_1.NesoiError.BaseError('UnknownError', _e.message);
60
+ error.stack = _e;
59
61
  }
60
62
  node.error = error;
61
63
  node.time.end = datetime_1.NesoiDatetime.now();
@@ -2,6 +2,7 @@ import { BuilderType } from "../schema";
2
2
  import { ResolvedBuilderNode } from './dependency';
3
3
  import { AnyModule } from './module';
4
4
  import { TreeshakeConfig } from "../compiler/treeshake";
5
+ import { ProgressiveBuildCache } from "../compiler/progressive";
5
6
  type TraverseCallback = (node: ResolvedBuilderNode) => Promise<void>;
6
7
  /**
7
8
  * A tree of module elements which allows building in the correct order.
@@ -23,7 +24,7 @@ export declare class ModuleTree {
23
24
  * - Resolves each found dependency forming a tree
24
25
  * - Groups tree into layers which can be built in isolation
25
26
  */
26
- resolve(): Promise<void>;
27
+ resolve(cache?: ProgressiveBuildCache): Promise<void>;
27
28
  /**
28
29
  * Read the module elements from files and identify
29
30
  * all related nodes.
@@ -82,5 +83,11 @@ export declare class ModuleTree {
82
83
  * @returns A list of resolved builder nodes
83
84
  */
84
85
  allNodes(): ResolvedBuilderNode[];
86
+ /**
87
+ * Return a list of all nodes of all modules on the tree.
88
+ *
89
+ * @returns A list of resolved builder nodes
90
+ */
91
+ allNodesByModule(): Record<string, ResolvedBuilderNode[]>;
85
92
  }
86
93
  export {};
@@ -6,6 +6,7 @@ const error_1 = require("../compiler/error");
6
6
  const log_1 = require("./util/log");
7
7
  const string_1 = require("./util/string");
8
8
  const treeshake_1 = require("../compiler/treeshake");
9
+ const progressive_1 = require("../compiler/progressive");
9
10
  /**
10
11
  * A tree of module elements which allows building in the correct order.
11
12
  *
@@ -27,8 +28,9 @@ class ModuleTree {
27
28
  * - Resolves each found dependency forming a tree
28
29
  * - Groups tree into layers which can be built in isolation
29
30
  */
30
- async resolve() {
31
- const nodesByModule = await this.treeshake();
31
+ async resolve(cache) {
32
+ cache ?? (cache = progressive_1.ProgressiveBuild.empty());
33
+ const nodesByModule = await this.treeshake(cache);
32
34
  const resolvedNodes = await this.resolveDependencies(nodesByModule);
33
35
  this.layers = this.resolveLayers(resolvedNodes);
34
36
  }
@@ -38,12 +40,12 @@ class ModuleTree {
38
40
  *
39
41
  * @returns A dictionary of nodes by module name
40
42
  */
41
- async treeshake() {
43
+ async treeshake(cache) {
42
44
  log_1.Log.debug('compiler', 'tree', 'Treeshaking');
43
45
  const nodesByModule = {};
44
46
  for (const m in this.modules) {
45
47
  const module = this.modules[m];
46
- const nodes = await treeshake_1.Treeshake.module(module, this.config);
48
+ const nodes = await treeshake_1.Treeshake.module(module, cache, this.config);
47
49
  nodesByModule[module.name] = nodes;
48
50
  }
49
51
  return nodesByModule;
@@ -89,27 +91,29 @@ class ModuleTree {
89
91
  return { node: resolved[dep.tag], soft: dep.soft };
90
92
  });
91
93
  const inlines = {};
92
- if ('_inlineNodes' in node.builder) {
93
- const inlineNodes = node.builder._inlineNodes;
94
- inlineNodes.forEach((inline) => {
95
- log_1.Log.trace('compiler', 'tree', ` └ ${(0, string_1.colored)('OK', 'green')} ${(0, string_1.colored)(inline.module + '::' + inline.type + ':' + inline.name, 'lightcyan')}`);
96
- // If inline node was not resolved yet, create a shared reference
97
- // on which the `dependencies` and `inlines` will be populated on future iterations.
98
- if (!(inline.tag in resolved)) {
99
- resolved[inline.tag] = {
100
- ...inline,
101
- dependencies: [],
102
- inlines: {}
103
- };
104
- }
105
- const type = inline.type;
106
- if (!(type in inlines)) {
107
- inlines[type] = {
108
- [inline.name]: resolved[inline.tag]
109
- };
110
- }
111
- inlines[type][inline.name] = resolved[inline.tag];
112
- });
94
+ if (!node.progressive) {
95
+ if ('_inlineNodes' in node.builder) {
96
+ const inlineNodes = node.builder._inlineNodes;
97
+ inlineNodes.forEach((inline) => {
98
+ log_1.Log.trace('compiler', 'tree', ` └ ${(0, string_1.colored)('OK', 'green')} ${(0, string_1.colored)(inline.module + '::' + inline.type + ':' + inline.name, 'lightcyan')}`);
99
+ // If inline node was not resolved yet, create a shared reference
100
+ // on which the `dependencies` and `inlines` will be populated on future iterations.
101
+ if (!(inline.tag in resolved)) {
102
+ resolved[inline.tag] = {
103
+ ...inline,
104
+ dependencies: [],
105
+ inlines: {}
106
+ };
107
+ }
108
+ const type = inline.type;
109
+ if (!(type in inlines)) {
110
+ inlines[type] = {
111
+ [inline.name]: resolved[inline.tag]
112
+ };
113
+ }
114
+ inlines[type][inline.name] = resolved[inline.tag];
115
+ });
116
+ }
113
117
  }
114
118
  // If node was already created when resolving a dependendant,
115
119
  // just fill the dependencies and inlines.
@@ -274,5 +278,21 @@ class ModuleTree {
274
278
  }
275
279
  return nodes;
276
280
  }
281
+ /**
282
+ * Return a list of all nodes of all modules on the tree.
283
+ *
284
+ * @returns A list of resolved builder nodes
285
+ */
286
+ allNodesByModule() {
287
+ var _a;
288
+ const modules = {};
289
+ for (const layer of this.layers) {
290
+ for (const node of layer) {
291
+ modules[_a = node.module] ?? (modules[_a] = []);
292
+ modules[node.module].push(node);
293
+ }
294
+ }
295
+ return modules;
296
+ }
277
297
  }
278
298
  exports.ModuleTree = ModuleTree;
@@ -1,3 +1,4 @@
1
1
  export declare class Hash {
2
- static file(filepath: string, algorithm: 'sha256' | 'sha1' | 'md5'): Promise<string>;
2
+ static file(filepath: string, algorithm?: 'sha256' | 'sha1' | 'md5'): Promise<string>;
3
+ static merge(tree: Record<string, string>, algorithm?: 'sha256' | 'sha1' | 'md5'): string;
3
4
  }
@@ -7,7 +7,7 @@ exports.Hash = void 0;
7
7
  const fs_1 = __importDefault(require("fs"));
8
8
  const crypto_1 = __importDefault(require("crypto"));
9
9
  class Hash {
10
- static file(filepath, algorithm) {
10
+ static file(filepath, algorithm = 'sha256') {
11
11
  return new Promise(resolve => {
12
12
  const fd = fs_1.default.createReadStream(filepath);
13
13
  const hash = crypto_1.default.createHash(algorithm);
@@ -19,5 +19,14 @@ class Hash {
19
19
  fd.pipe(hash);
20
20
  });
21
21
  }
22
+ static merge(tree, algorithm = 'sha256') {
23
+ const str = Object.entries(tree)
24
+ .map((key, value) => `${key}:${value}`)
25
+ .sort()
26
+ .join('\n');
27
+ return crypto_1.default.createHash(algorithm)
28
+ .update(str)
29
+ .digest('hex');
30
+ }
22
31
  }
23
32
  exports.Hash = Hash;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nesoi",
3
- "version": "3.0.12",
3
+ "version": "3.0.14",
4
4
  "description": "Declarative framework for data-driven applications",
5
5
  "repository": {
6
6
  "type": "git",