@static-suite/static-suite-data-server 0.0.1 → 0.0.3

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 (146) hide show
  1. package/README.md +569 -107
  2. package/dist/http/README.md +569 -107
  3. package/dist/http/routes/dependency.d.ts +10 -0
  4. package/dist/http/routes/dependency.d.ts.map +1 -0
  5. package/dist/http/routes/dependency.js +71 -0
  6. package/dist/http/routes/dump.d.ts.map +1 -1
  7. package/dist/http/routes/dump.js +15 -10
  8. package/dist/http/routes/home.js +2 -1
  9. package/dist/http/routes/index.d.ts.map +1 -1
  10. package/dist/http/routes/index.js +8 -0
  11. package/dist/http/routes/status.d.ts.map +1 -1
  12. package/dist/http/routes/status.js +1 -6
  13. package/dist/http/views/dependencyIndex.pug +14 -0
  14. package/dist/lib/dataServer.d.ts +2 -1
  15. package/dist/lib/dataServer.d.ts.map +1 -1
  16. package/dist/lib/query/query.types.d.ts +2 -2
  17. package/dist/lib/query/query.types.d.ts.map +1 -1
  18. package/dist/lib/query/query.types.js +2 -2
  19. package/dist/lib/query/queryRunner.d.ts.map +1 -1
  20. package/dist/lib/query/queryRunner.js +3 -1
  21. package/dist/lib/store/dataDir/dataDir.types.d.ts +5 -5
  22. package/dist/lib/store/dataDir/dataDir.types.d.ts.map +1 -1
  23. package/dist/lib/store/dataDir/dataDirManager.d.ts.map +1 -1
  24. package/dist/lib/store/dataDir/dataDirManager.js +23 -12
  25. package/dist/lib/store/dependency/dependency.types.d.ts.map +1 -1
  26. package/dist/lib/store/dependency/dependencyFileHelper.d.ts +1 -1
  27. package/dist/lib/store/dependency/dependencyFileHelper.d.ts.map +1 -1
  28. package/dist/lib/store/dependency/dependencyFileHelper.js +5 -3
  29. package/dist/lib/store/dependency/dependencyManager.d.ts +12 -0
  30. package/dist/lib/store/dependency/dependencyManager.d.ts.map +1 -1
  31. package/dist/lib/store/dependency/dependencyManager.js +7 -5
  32. package/dist/lib/store/dependency/dependencyTagger.d.ts.map +1 -1
  33. package/dist/lib/store/dependency/dependencyTagger.js +3 -38
  34. package/dist/lib/store/diff/{diffManager.types.d.ts → diff.types.d.ts} +14 -6
  35. package/dist/lib/store/diff/diff.types.d.ts.map +1 -0
  36. package/dist/lib/store/{dependency/dependencyManager.types.js → diff/diff.types.js} +0 -0
  37. package/dist/lib/store/diff/diffManager.d.ts +1 -1
  38. package/dist/lib/store/diff/diffManager.d.ts.map +1 -1
  39. package/dist/lib/store/diff/diffManager.js +38 -81
  40. package/dist/lib/store/dump/{dumpManager.types.d.ts → dump.types.d.ts} +21 -8
  41. package/dist/lib/store/dump/dump.types.d.ts.map +1 -0
  42. package/dist/lib/store/{diff/diffManager.types.js → dump/dump.types.js} +0 -0
  43. package/dist/lib/store/dump/dumpManager.d.ts +1 -1
  44. package/dist/lib/store/dump/dumpManager.d.ts.map +1 -1
  45. package/dist/lib/store/dump/dumpManager.js +31 -56
  46. package/dist/lib/store/dump/dumpMetadataHelper.d.ts +7 -0
  47. package/dist/lib/store/dump/dumpMetadataHelper.d.ts.map +1 -0
  48. package/dist/lib/store/dump/dumpMetadataHelper.js +61 -0
  49. package/dist/lib/store/hook/hook.types.d.ts +49 -23
  50. package/dist/lib/store/hook/hook.types.d.ts.map +1 -1
  51. package/dist/lib/store/hook/hookManager.d.ts.map +1 -1
  52. package/dist/lib/store/hook/hookManager.js +19 -8
  53. package/dist/lib/store/store.d.ts.map +1 -1
  54. package/dist/lib/store/store.js +9 -4
  55. package/dist/lib/store/store.types.d.ts +14 -37
  56. package/dist/lib/store/store.types.d.ts.map +1 -1
  57. package/dist/lib/store/storeManager.d.ts.map +1 -1
  58. package/dist/lib/store/storeManager.js +20 -10
  59. package/dist/lib/store/workDir/storage/getChangedLinesBetween.d.ts +16 -0
  60. package/dist/lib/store/workDir/storage/getChangedLinesBetween.d.ts.map +1 -0
  61. package/dist/lib/store/workDir/storage/{getChangedLinesSince.js → getChangedLinesBetween.js} +22 -20
  62. package/dist/lib/store/workDir/storage/getDataFromLogLine.d.ts.map +1 -1
  63. package/dist/lib/store/workDir/storage/getDataFromLogLine.js +16 -3
  64. package/dist/lib/store/workDir/storage/index.d.ts +1 -1
  65. package/dist/lib/store/workDir/storage/index.d.ts.map +1 -1
  66. package/dist/lib/store/workDir/storage/index.js +1 -1
  67. package/dist/lib/store/workDir/workDir.types.d.ts +9 -1
  68. package/dist/lib/store/workDir/workDir.types.d.ts.map +1 -1
  69. package/dist/lib/store/workDir/workDirHelper.d.ts +13 -6
  70. package/dist/lib/store/workDir/workDirHelper.d.ts.map +1 -1
  71. package/dist/lib/store/workDir/workDirHelper.js +42 -11
  72. package/dist/lib/utils/fs/fsUtils.d.ts +6 -0
  73. package/dist/lib/utils/fs/fsUtils.d.ts.map +1 -1
  74. package/dist/lib/utils/fs/fsUtils.js +20 -1
  75. package/dist/lib/utils/module/moduleManager.d.ts.map +1 -1
  76. package/dist/lib/utils/module/moduleManager.js +5 -1
  77. package/dist/lib/utils/string/stringUtils.d.ts +14 -0
  78. package/dist/lib/utils/string/stringUtils.d.ts.map +1 -1
  79. package/dist/lib/utils/string/stringUtils.js +28 -1
  80. package/dist/static-suite-data-server.d.ts +19 -39
  81. package/package.json +3 -3
  82. package/src/http/routes/dependency.ts +91 -0
  83. package/src/http/routes/dump.ts +21 -10
  84. package/src/http/routes/home.ts +2 -2
  85. package/src/http/routes/index.ts +16 -0
  86. package/src/http/routes/status.ts +1 -9
  87. package/src/http/views/dependencyIndex.pug +14 -0
  88. package/src/lib/dataServer.ts +2 -0
  89. package/src/lib/query/query.types.ts +2 -2
  90. package/src/lib/query/queryRunner.ts +3 -1
  91. package/src/lib/store/dataDir/dataDir.types.ts +5 -5
  92. package/src/lib/store/dataDir/dataDirManager.ts +30 -14
  93. package/src/lib/store/dependency/dependency.types.ts +0 -5
  94. package/src/lib/store/dependency/dependencyFileHelper.ts +5 -3
  95. package/src/lib/store/dependency/dependencyManager.ts +6 -3
  96. package/src/lib/store/dependency/dependencyTagger.ts +3 -39
  97. package/src/lib/store/diff/{diffManager.types.ts → diff.types.ts} +14 -5
  98. package/src/lib/store/diff/diffManager.ts +45 -84
  99. package/src/lib/store/dump/{dumpManager.types.ts → dump.types.ts} +24 -7
  100. package/src/lib/store/dump/dumpManager.ts +40 -75
  101. package/src/lib/store/dump/dumpMetadataHelper.ts +73 -0
  102. package/src/lib/store/hook/hook.types.ts +58 -23
  103. package/src/lib/store/hook/hookManager.ts +24 -9
  104. package/src/lib/store/store.ts +9 -4
  105. package/src/lib/store/store.types.ts +16 -37
  106. package/src/lib/store/storeManager.ts +28 -12
  107. package/src/lib/store/workDir/__tests__/workDirHelper.test.ts +6 -1
  108. package/src/lib/store/workDir/storage/__tests__/{getChangedLinesSince.test.ts → getChangedLinesBetween.test.ts} +9 -4
  109. package/src/lib/store/workDir/storage/getChangedLinesBetween.ts +52 -0
  110. package/src/lib/store/workDir/storage/getDataFromLogLine.ts +22 -3
  111. package/src/lib/store/workDir/storage/index.ts +1 -1
  112. package/src/lib/store/workDir/workDir.types.ts +11 -1
  113. package/src/lib/store/workDir/workDirHelper.ts +45 -11
  114. package/src/lib/utils/fs/fsUtils.ts +18 -0
  115. package/src/lib/utils/module/moduleManager.ts +5 -1
  116. package/src/lib/utils/string/__tests__/stringUtils.test.ts +30 -1
  117. package/src/lib/utils/string/stringUtils.ts +32 -0
  118. package/dist/lib/query/queryRunner copy.d.ts +0 -3
  119. package/dist/lib/query/queryRunner copy.d.ts.map +0 -1
  120. package/dist/lib/query/queryRunner copy.js +0 -87
  121. package/dist/lib/store/dependency/dependencyManager copy.d.ts +0 -6
  122. package/dist/lib/store/dependency/dependencyManager copy.d.ts.map +0 -1
  123. package/dist/lib/store/dependency/dependencyManager copy.js +0 -91
  124. package/dist/lib/store/dependency/dependencyManager.types.d.ts +0 -48
  125. package/dist/lib/store/dependency/dependencyManager.types.d.ts.map +0 -1
  126. package/dist/lib/store/dependency/dependencyTagManager.d.ts +0 -6
  127. package/dist/lib/store/dependency/dependencyTagManager.d.ts.map +0 -1
  128. package/dist/lib/store/dependency/dependencyTagManager.js +0 -33
  129. package/dist/lib/store/diff/diffManager.types.d.ts.map +0 -1
  130. package/dist/lib/store/diff/tracker.d.ts +0 -3
  131. package/dist/lib/store/diff/tracker.d.ts.map +0 -1
  132. package/dist/lib/store/diff/tracker.js +0 -82
  133. package/dist/lib/store/diff/tracker.types.d.ts +0 -31
  134. package/dist/lib/store/diff/tracker.types.d.ts.map +0 -1
  135. package/dist/lib/store/diff/tracker.types.js +0 -2
  136. package/dist/lib/store/dump/dumpManager.types.d.ts.map +0 -1
  137. package/dist/lib/store/dump/dumpManager.types.js +0 -2
  138. package/dist/lib/store/include/includeIndex.d.ts +0 -6
  139. package/dist/lib/store/include/includeIndex.d.ts.map +0 -1
  140. package/dist/lib/store/include/includeIndex.js +0 -65
  141. package/dist/lib/store/include/includeIndex.types.d.ts +0 -29
  142. package/dist/lib/store/include/includeIndex.types.d.ts.map +0 -1
  143. package/dist/lib/store/include/includeIndex.types.js +0 -2
  144. package/dist/lib/store/workDir/storage/getChangedLinesSince.d.ts +0 -9
  145. package/dist/lib/store/workDir/storage/getChangedLinesSince.d.ts.map +0 -1
  146. package/src/lib/store/workDir/storage/getChangedLinesSince.ts +0 -47
@@ -20,6 +20,15 @@ import {
20
20
  dumpMetadataShow,
21
21
  dumpMetadataReset,
22
22
  } from './dump';
23
+ import {
24
+ dependencyIndex,
25
+ dependencyInvalidatedFilepaths,
26
+ dependencyExplicitlyInvalidatedTags,
27
+ dependencyAllInvalidatedTags,
28
+ dependencyTreeReversed,
29
+ dependencyTreeRoute,
30
+ dependencyTagParents,
31
+ } from './dependency';
23
32
 
24
33
  const routes = Router();
25
34
 
@@ -42,6 +51,13 @@ routes.get('/dump/incremental', dumpIncremental);
42
51
  routes.get('/dump/full', dumpFull);
43
52
  routes.get('/dump/metadata/show', dumpMetadataShow);
44
53
  routes.get('/dump/metadata/reset', dumpMetadataReset);
54
+ routes.get('/dependency/tree/reversed', dependencyTreeReversed);
55
+ routes.get('/dependency/tree', dependencyTreeRoute);
56
+ routes.get('/dependency/invalidated/tags', dependencyExplicitlyInvalidatedTags);
57
+ routes.get('/dependency/invalidated/tags/all', dependencyAllInvalidatedTags);
58
+ routes.get('/dependency/invalidated/filepaths', dependencyInvalidatedFilepaths);
59
+ routes.get('/dependency/tag/parents', dependencyTagParents);
60
+ routes.get('/dependency', dependencyIndex);
45
61
  routes.get(['/data/*', '/data'], data);
46
62
 
47
63
  export default routes;
@@ -8,11 +8,6 @@ import { store } from '@lib/store';
8
8
  import { jsonify } from '@lib/utils/object';
9
9
  import { diffManager } from '@lib/store/diff/diffManager';
10
10
  import { ObjectType } from '@lib/utils/object/object.types';
11
- import { dependencyManager } from '@lib/store/dependency/dependencyManager';
12
- import {
13
- dependencyTree,
14
- getReversedDependencyTree,
15
- } from '@lib/store/dependency/dependencyTagger';
16
11
 
17
12
  const statusIndex = (req: Request, res: Response): void => {
18
13
  res.render('statusIndex', {
@@ -32,14 +27,11 @@ const statusBasic = (req: Request, res: Response): void => {
32
27
 
33
28
  const response = {
34
29
  config,
35
- dataDirLastUpdate: dataDirManager.getModificationDate(),
30
+ dataDirLastUpdate: dataDirManager.getModificationUniqueId(),
36
31
  query: {
37
32
  numberOfExecutions: queryRunner.getCount(),
38
33
  numberOfCachedQueries: cache.bin('query').size,
39
34
  },
40
- dependencyTree: jsonify(dependencyTree),
41
- reversedDependencyTree: jsonify(getReversedDependencyTree()),
42
- invalidatedFilepaths: dependencyManager.getInvalidatedFilepaths(),
43
35
  };
44
36
 
45
37
  res.status(200);
@@ -0,0 +1,14 @@
1
+ extends includes/layout.pug
2
+
3
+ block vars
4
+ - var title = "Dependency | Static Suite Data Server"
5
+
6
+ block content
7
+ h1(class="title is-1")="Dependency"
8
+ table(class="table is-fullwidth is-hoverable")
9
+ tbody
10
+ each description, link in links
11
+ tr
12
+ td
13
+ a(href=link)= link
14
+ td=description
@@ -7,6 +7,7 @@ import { store } from '@lib/store';
7
7
  import { Store } from '@lib/store/store.types';
8
8
  import { queryRunner } from '@lib/query';
9
9
  import { taskRunner } from '@lib/task/taskRunner';
10
+ import { TaskRunner } from '@lib/task/task.types';
10
11
  import {
11
12
  QueryRunner,
12
13
  QuerySuccessfulResponse,
@@ -77,5 +78,6 @@ export {
77
78
  QueryErrorResponse,
78
79
  QueryArgs,
79
80
  QueryModule,
81
+ TaskRunner,
80
82
  CacheStatus,
81
83
  };
@@ -99,8 +99,8 @@ export type QueryModuleResult = {
99
99
  * @public
100
100
  */
101
101
  export enum CacheStatus {
102
- MISS,
103
- HIT,
102
+ MISS = 'miss',
103
+ HIT = 'hit',
104
104
  }
105
105
 
106
106
  /**
@@ -74,12 +74,14 @@ export const queryRunner: QueryRunner = {
74
74
  queryCache.set(cacheId, queryResult);
75
75
  }
76
76
 
77
- // Set tags for this query.
77
+ // Set tags for this query, replacing any other, because query
78
+ // dependencies are set only by their "tags" field.
78
79
  const queryTags =
79
80
  queryResponse.tags && queryResponse.tags?.length > 0
80
81
  ? queryResponse.tags
81
82
  : ['*'];
82
83
  dependencyTagger.setDependency(queryDefinition, queryTags);
84
+ queryResult.tags = queryTags;
83
85
  } catch (e) {
84
86
  // Log error and rethrow.
85
87
  logger.error(
@@ -23,16 +23,16 @@ export type DataDirManager = {
23
23
  update(): ChangedFiles;
24
24
 
25
25
  /**
26
- * Get date of last modification of data directory.
26
+ * Get unique id of last modification of data directory.
27
27
  *
28
28
  * @remarks
29
29
  * Metadata about when and how is the data directory updated is
30
30
  * stored in the work directory. If that directory is not present or
31
- * not initialized with proper data, it returns the sync date of the store.
32
- * If the store is not yet loaded, it returns a date in the past,
31
+ * not initialized with proper data, it returns the unique id of the store.
32
+ * If the store is not yet loaded, it returns a unique id in the past,
33
33
  * the Unix Epoch (00:00:00 UTC on 1 January 1970).
34
34
  *
35
- * @returns The date of last modification of data directory
35
+ * @returns The unique id of last modification of data directory
36
36
  */
37
- getModificationDate(): Date;
37
+ getModificationUniqueId(): string;
38
38
  };
@@ -3,7 +3,7 @@ import { config } from '@lib/config';
3
3
  import { store } from '@lib/store';
4
4
  import { findFilesInDir } from '@lib/utils/fs';
5
5
  import { logger } from '@lib/utils/logger';
6
- import { workDirHelper } from '@lib/store/workDir';
6
+ import { unixEpochUniqueId, workDirHelper } from '@lib/store/workDir';
7
7
  import { cache } from '@lib/utils/cache';
8
8
  import { storeManager } from '@lib/store/storeManager';
9
9
  import { hookManager } from '@lib/store/hook';
@@ -13,6 +13,8 @@ import { DataDirManager } from './dataDir.types';
13
13
  import { ChangedFiles } from '../workDir/workDir.types';
14
14
  import { dependencyManager } from '../dependency/dependencyManager';
15
15
 
16
+ let initialUniqueIdAlreadySet = false;
17
+
16
18
  export const dataDirManager: DataDirManager = {
17
19
  load: () => {
18
20
  logger.info('Loading data dir...');
@@ -28,11 +30,18 @@ export const dataDirManager: DataDirManager = {
28
30
  hookManager.reset();
29
31
  queryManager.reset();
30
32
  taskManager.reset();
33
+ dependencyManager.reset();
31
34
 
32
35
  // Invoke "store load start" hook.
33
36
  hookManager.invokeOnStoreLoadStart();
34
37
 
35
- store.syncDate = dataDirManager.getModificationDate();
38
+ const modificationUniqueId = dataDirManager.getModificationUniqueId();
39
+ if (!initialUniqueIdAlreadySet) {
40
+ store.initialUniqueId = modificationUniqueId;
41
+ initialUniqueIdAlreadySet = true;
42
+ }
43
+ store.currentUniqueId = modificationUniqueId;
44
+ logger.info(`Found unique id: ${store.currentUniqueId}`);
36
45
 
37
46
  // Add all files, one by one.
38
47
  const relativeFilePaths = findFilesInDir(config.dataDir);
@@ -62,29 +71,34 @@ export const dataDirManager: DataDirManager = {
62
71
  },
63
72
 
64
73
  update: () => {
65
- const dataDirModificationDate = dataDirManager.getModificationDate();
74
+ const dataDirModificationUniqueId =
75
+ dataDirManager.getModificationUniqueId();
66
76
 
67
77
  let changedFiles: ChangedFiles = {
68
78
  updated: [],
69
79
  deleted: [],
80
+ fromUniqueId: store.currentUniqueId,
81
+ toUniqueId: dataDirModificationUniqueId,
70
82
  };
71
83
 
72
- if (store.syncDate) {
73
- if (dataDirModificationDate > store.syncDate) {
74
- // Save store.syncDate to a variable and set it ASAP to avoid two concurrent
75
- // processes updating the data directory at the same time.
76
- const storeLastSyncDate = store.syncDate;
77
- store.syncDate = dataDirModificationDate;
84
+ if (store.currentUniqueId) {
85
+ if (dataDirModificationUniqueId > store.currentUniqueId) {
86
+ // Save store.syncDate to a variable and set it ASAP.
87
+ const storeLastUniqueId = store.currentUniqueId;
88
+ store.currentUniqueId = dataDirModificationUniqueId;
78
89
  const startDate = microtime.now();
79
90
  logger.debug(
80
- `Data dir outdated. Current data loaded at ${storeLastSyncDate.toISOString()} but last updated at ${dataDirModificationDate.toISOString()}`,
91
+ `Data dir outdated. Current unique id in memory is ${storeLastUniqueId} but data dir is ${dataDirModificationUniqueId}`,
81
92
  );
82
93
 
83
94
  // Before updating anything, track down which filepaths are invalidated with
84
95
  // the current set of dependencies, before those dependencies change.
85
96
  dependencyManager.trackInvalidatedFilepaths();
86
97
 
87
- changedFiles = workDirHelper.getChangedFilesSince(storeLastSyncDate);
98
+ changedFiles = workDirHelper.getChangedFilesBetween(
99
+ storeLastUniqueId,
100
+ dataDirModificationUniqueId,
101
+ );
88
102
  hookManager.invokeOnStoreChangeStart(changedFiles);
89
103
  changedFiles.updated.forEach(file => {
90
104
  storeManager.update(file);
@@ -107,7 +121,7 @@ export const dataDirManager: DataDirManager = {
107
121
  logger.debug(`Data dir updated in ${execTimeMs}ms.`);
108
122
  } else {
109
123
  logger.debug(
110
- `Data dir up to date. Current data loaded at ${store.syncDate.toISOString()} and last updated at ${dataDirModificationDate.toISOString()}`,
124
+ `Data dir up to date. Current unique id in memory is ${store.currentUniqueId} and data dir is ${dataDirModificationUniqueId}`,
111
125
  );
112
126
  }
113
127
  } else {
@@ -116,6 +130,8 @@ export const dataDirManager: DataDirManager = {
116
130
  return changedFiles;
117
131
  },
118
132
 
119
- getModificationDate: (): Date =>
120
- workDirHelper.getModificationDate() || store.syncDate || new Date(0),
133
+ getModificationUniqueId: (): string =>
134
+ workDirHelper.getModificationUniqueId() ||
135
+ store.currentUniqueId ||
136
+ unixEpochUniqueId,
121
137
  };
@@ -37,11 +37,6 @@ export type DependencyTagger = {
37
37
  * @param tags - The list of tags for which to invalidate dependency items.
38
38
  */
39
39
  invalidateTags(tags: string[]): void;
40
-
41
- /**
42
- * Resets the list of invalidated tags once consumed.
43
- */
44
- // resetInvalidatedTags(): void;
45
40
  };
46
41
 
47
42
  /**
@@ -2,17 +2,17 @@ import { Json } from '@lib/utils/object/object.types';
2
2
  import { dependencyTagger } from './dependencyTagger';
3
3
 
4
4
  export const dependencyIncludeHelper = {
5
- setIncludeDependencies: (filepath: string, json: Json): void => {
5
+ addIncludeDependencies: (filepath: string, json: Json): void => {
6
6
  const includes = json?.metadata?.includes;
7
7
 
8
8
  if (includes?.static) {
9
9
  const staticIncludes = Object.values(includes?.static);
10
- dependencyTagger.setDependency(filepath, staticIncludes);
10
+ dependencyTagger.addDependency(filepath, staticIncludes);
11
11
  }
12
12
 
13
13
  if (includes?.dynamic) {
14
14
  const dynamicIncludes = Object.values(includes?.dynamic);
15
- dependencyTagger.setDependency(filepath, dynamicIncludes);
15
+ dependencyTagger.addDependency(filepath, dynamicIncludes);
16
16
  // Queries are invalidated by any data change until they are executed,
17
17
  // when they return their dependencies. They are "globally invalidable" when:
18
18
  // 1) Are added for the first time
@@ -24,6 +24,8 @@ export const dependencyIncludeHelper = {
24
24
  // 2) When that query is executed, it has a dependency on "node:1234"
25
25
  // 3) When that file with a query is updated, the query has again a dependency on "*"
26
26
  dynamicIncludes.forEach(queryDefinition => {
27
+ // This is explicity a "set" operation, because query dependencies are
28
+ // only set from a query's "tags" field.
27
29
  dependencyTagger.setDependency(queryDefinition, ['*']);
28
30
  });
29
31
  }
@@ -10,7 +10,10 @@ const invalidatedFilepaths = {
10
10
  /**
11
11
  * Gets a list of parents of a dependency tag
12
12
  */
13
- const getTagParents = (tag: string, parents = new Set<string>()) => {
13
+ export const getTagParents = (
14
+ tag: string,
15
+ parents = new Set<string>(),
16
+ ): Set<string> => {
14
17
  getReversedDependencyTree()
15
18
  .get(tag)
16
19
  ?.forEach(parent => {
@@ -29,7 +32,7 @@ const getTagParents = (tag: string, parents = new Set<string>()) => {
29
32
  * Iterates over all explicitly invalidated tags, and obtains all
30
33
  * its parents.
31
34
  */
32
- const getInvalidatedTags = (): string[] => {
35
+ export const getAllInvalidatedTags = (): string[] => {
33
36
  const allInvalidatedTags = new Set<string>();
34
37
  const invalidatedTagsArray = Array.from(invalidatedTags);
35
38
  if (invalidatedTagsArray.length > 0) {
@@ -54,7 +57,7 @@ const getInvalidatedTags = (): string[] => {
54
57
  */
55
58
  export const dependencyManager: DependencyManager = {
56
59
  trackInvalidatedFilepaths: () => {
57
- const allInvalidatedTags = getInvalidatedTags();
60
+ const allInvalidatedTags = getAllInvalidatedTags();
58
61
  allInvalidatedTags.forEach(invalidatedTag => {
59
62
  if (store.deleted.has(invalidatedTag)) {
60
63
  invalidatedFilepaths.deleted.add(invalidatedTag);
@@ -61,45 +61,9 @@ export const dependencyTagger: DependencyTagger = {
61
61
 
62
62
  invalidateTags: tags => {
63
63
  tags.forEach(tag => {
64
- invalidatedTags.add(tag);
65
- });
66
- },
67
- };
68
-
69
- /*
70
- import { DependencyTagger } from './dependency.types';
71
-
72
- export const dependencyTree = new Map<string, Set<string>>();
73
-
74
- export const invalidatedTags = new Set<string>();
75
-
76
- export const dependencyTagger: DependencyTagger = {
77
- setDependency: (tag, dependsOnTags) => {
78
- dependsOnTags.forEach(dependsOnTag => {
79
- const previousData = dependencyTree.get(dependsOnTag);
80
- if (previousData) {
81
- previousData.add(tag);
82
- } else {
83
- dependencyTree.set(dependsOnTag, new Set<string>([tag]));
84
- }
85
- });
86
- },
87
-
88
- deleteDependency: (tag, dependsOnTags) => {
89
- dependsOnTags.forEach(dependsOnTag => {
90
- const previousData = dependencyTree.get(dependsOnTag);
91
- if (previousData) {
92
- previousData.delete(tag);
93
- if (previousData.size === 0) {
94
- dependencyTree.delete(dependsOnTag);
95
- }
64
+ if (tag) {
65
+ invalidatedTags.add(tag);
96
66
  }
97
67
  });
98
68
  },
99
-
100
- invalidateTags: tags => {
101
- tags.forEach(tag => {
102
- invalidatedTags.add(tag);
103
- });
104
- },
105
- }; */
69
+ };
@@ -3,11 +3,11 @@
3
3
  */
4
4
  export type DiffManager = {
5
5
  /**
6
- * Clears intermediate changes tracked by trackChangedFile().
6
+ * Clears intermediate changes tracked by dependency manager.
7
7
  *
8
- * @param date - Date to be used as a timestamp for the next diff.
8
+ * @param uniqueId - Unique id to be used for the next diff.
9
9
  */
10
- reset(date: Date): void;
10
+ reset(uniqueId: string): void;
11
11
 
12
12
  /**
13
13
  * Gets a list of changed files affected by includes and queries.
@@ -35,9 +35,18 @@ export type DiffManager = {
35
35
  */
36
36
  export type Diff = {
37
37
  /**
38
- * Timestamp in milliseconds.
38
+ * Execution time taken by the diff, in milliseconds.
39
39
  */
40
- since: number;
40
+ execTimeMs: number;
41
+ /**
42
+ * A unique id representing the date from which this diff is obtained.
43
+ */
44
+ fromUniqueId: string;
45
+
46
+ /**
47
+ * A unique id representing the date until which this diff is obtained.
48
+ */
49
+ toUniqueId: string;
41
50
 
42
51
  /**
43
52
  * A list of updated files (both newly added and changed files).
@@ -1,115 +1,76 @@
1
1
  import microtime from 'microtime';
2
2
  import { logger } from '@lib/utils/logger';
3
3
  import { store } from '../store';
4
- import { DiffManager, Diff } from './diffManager.types';
4
+ import { DiffManager, Diff } from './diff.types';
5
5
  import { dataDirManager } from '../dataDir/dataDirManager';
6
6
  import { dependencyManager } from '../dependency/dependencyManager';
7
+ import { unixEpochUniqueId, workDirHelper } from '../workDir';
8
+ import { dumpMetadataHelper } from '../dump/dumpMetadataHelper';
7
9
 
8
- let lastDiffDate: Date | null = null;
10
+ let lastDiffUniqueId: string = unixEpochUniqueId;
9
11
 
10
12
  export const diffManager: DiffManager = {
11
- reset(date: Date): void {
12
- lastDiffDate = date;
13
+ reset(uniqueId: string): void {
14
+ lastDiffUniqueId = uniqueId;
13
15
  dependencyManager.reset();
14
16
  },
15
17
 
16
- getDiff(options = { incremental: true }): Diff {
17
- const startDate = microtime.now();
18
-
19
- // Before getting any diff data, update any pending changes from data dir.
20
- dataDirManager.update();
21
-
22
- let updated = new Set<string>();
23
- let deleted = new Set<string>();
24
- if (options.incremental && lastDiffDate) {
25
- logger.debug(`Getting incremental diff using date "${lastDiffDate}"`);
26
- const invalidatedFilepaths = dependencyManager.getInvalidatedFilepaths();
27
- updated = new Set<string>(invalidatedFilepaths.updated);
28
- deleted = new Set<string>(invalidatedFilepaths.deleted);
29
- } else {
30
- // If no sinceDate is passed, return all files
31
- logger.debug(`Getting full diff with no date`);
32
- updated = new Set<string>(store.data.keys());
33
- }
34
-
35
- const diff: Diff = {
36
- since: lastDiffDate ? lastDiffDate.getTime() : new Date(0).getTime(),
37
- updated,
38
- deleted,
39
- };
40
-
41
- logger.info(
42
- `Diff created in ${(microtime.now() - startDate) / 1000} ms. Updated: ${
43
- diff.updated.size
44
- } / Deleted: ${diff.deleted.size}`,
45
- );
46
-
47
- // Log diff if not empty
48
- // if (diff.updated.length || diff.deleted.length) {
49
- // logger.debug(`Diff: "${JSON.stringify(jsonify(diff))}"`);
50
- // }
51
-
52
- return diff;
53
- },
54
-
55
- /*
56
18
  getDiff(options = { incremental: true }): Diff {
57
19
  const startDate = microtime.now();
58
20
 
59
21
  // Before getting any diff data, update any pending changes from data dir.
60
22
  const changedFiles = dataDirManager.update();
61
23
 
62
- let updated = new Set<string>();
63
- let deleted = new Set<string>();
64
- const sinceDate = getLastDiffDate();
65
- if (options.incremental && sinceDate) {
66
- logger.debug(`Getting incremental diff using date "${sinceDate}"`);
67
- // Only process changedFiles if not empty.
68
- if (changedFiles.updated.length || changedFiles.deleted.length) {
69
- // Update tracked files so no affected parent is missed.
70
- changedFiles.updated.forEach(file => {
71
- tracker.trackChangedFile(file);
72
- });
73
- changedFiles.deleted.forEach(file => {
74
- tracker.trackChangedFile(file);
75
- });
24
+ const updated = new Set<string>();
25
+ const deleted = new Set<string>();
26
+
27
+ const currentDumpUniqueId = dumpMetadataHelper.getCurrentDumpUniqueId();
28
+ const isFirstDiffAfterReboot = lastDiffUniqueId === unixEpochUniqueId;
29
+ const isADumpAvailable = currentDumpUniqueId !== unixEpochUniqueId;
30
+ // If both checks passes, check if something has changed after last dump to avoid a full diff:
31
+ if (isFirstDiffAfterReboot && isADumpAvailable) {
32
+ const dataDirModificationUniqueId = changedFiles.toUniqueId;
33
+ if (currentDumpUniqueId === store.initialUniqueId) {
34
+ // If nothing changed, use store.initialUniqueId as lastDiffUniqueId, to
35
+ // execute an incremental dump.
36
+ lastDiffUniqueId = store.initialUniqueId;
37
+ } else {
38
+ // If something changed, keep lastDiffUniqueId as is, and get the list of
39
+ // changed files from last dump. From that list, we need deleted files, since
40
+ // those files are no more in data dir and we need to remove them from dump dir.
41
+ const changedFilesSinceLastDump = workDirHelper.getChangedFilesBetween(
42
+ currentDumpUniqueId,
43
+ dataDirModificationUniqueId,
44
+ );
45
+ changedFilesSinceLastDump.deleted.forEach(filepath =>
46
+ deleted.add(filepath),
47
+ );
76
48
  }
49
+ }
77
50
 
78
- // Create the resulting set of updated and deleted files.
79
- // "updated" includes all affected parents tracked down
80
- // by tracker, without any deleted file.
81
- updated = new Set<string>(tracker.getChangedFiles());
82
- changedFiles.deleted.forEach(file => updated.delete(file));
83
-
84
- // "deleted" includes only deleted files, and is based only
85
- // on data coming from changedFiles, because all deleted files
86
- // are stored on Static Suite Data Server log
87
- deleted = new Set<string>(changedFiles.deleted);
88
-
89
- // Add updated files affected by queries only if "updated" or "deleted"
90
- // contain any changes.
91
- if (updated.size > 0 || deleted.size > 0) {
92
- queryTagManager
93
- .getInvalidFilepaths()
94
- .forEach(file => updated.add(file));
95
- queryTagManager.resetInvalidatedTags();
96
- }
51
+ if (options.incremental && lastDiffUniqueId !== unixEpochUniqueId) {
52
+ logger.debug(`Getting incremental diff using date "${lastDiffUniqueId}"`);
53
+ const invalidatedFilepaths = dependencyManager.getInvalidatedFilepaths();
54
+ invalidatedFilepaths.updated.forEach(filepath => updated.add(filepath));
55
+ invalidatedFilepaths.deleted.forEach(filepath => deleted.add(filepath));
97
56
  } else {
98
- // If no sinceDate is passed, return all files
57
+ // Return all files
99
58
  logger.debug(`Getting full diff with no date`);
100
- updated = new Set<string>(store.data.keys());
59
+ Array.from(store.data.keys()).forEach(key => updated.add(key));
101
60
  }
102
61
 
62
+ const execTimeMs = (microtime.now() - startDate) / 1000;
63
+
103
64
  const diff: Diff = {
104
- since: sinceDate ? sinceDate.getTime() : new Date(0).getTime(),
65
+ execTimeMs,
66
+ fromUniqueId: lastDiffUniqueId,
67
+ toUniqueId: changedFiles.toUniqueId,
105
68
  updated,
106
69
  deleted,
107
70
  };
108
71
 
109
72
  logger.info(
110
- `Diff created in ${(microtime.now() - startDate) / 1000} ms. Updated: ${
111
- diff.updated.size
112
- } / Deleted: ${diff.deleted.size}`,
73
+ `Diff created in ${execTimeMs} ms. Updated: ${diff.updated.size} / Deleted: ${diff.deleted.size}`,
113
74
  );
114
75
 
115
76
  // Log diff if not empty
@@ -118,5 +79,5 @@ export const diffManager: DiffManager = {
118
79
  // }
119
80
 
120
81
  return diff;
121
- }, */
82
+ },
122
83
  };
@@ -1,3 +1,5 @@
1
+ import { Diff } from '../diff/diff.types';
2
+
1
3
  /**
2
4
  * Service that dumps resolved data (with resolved includes) into a dump directory.
3
5
  */
@@ -20,11 +22,11 @@ export type DumpManager = {
20
22
  * Reset dump metadata.
21
23
  *
22
24
  * @remarks
23
- * Resets dump metadata, removing any dump information older than the passed timestamp.
25
+ * Resets dump metadata, removing any dump information older than the passed unique id.
24
26
  *
25
- * @param timestamp - Timestamp
27
+ * @param uniqueId - Unique id
26
28
  */
27
- reset(timestamp: number): void;
29
+ reset(uniqueId: string): void;
28
30
  };
29
31
 
30
32
  /**
@@ -32,9 +34,19 @@ export type DumpManager = {
32
34
  */
33
35
  export type Dump = {
34
36
  /**
35
- * Timestamp in milliseconds.
37
+ * Execution time taken by the dump, in milliseconds.
36
38
  */
37
- since: number;
39
+ execTimeMs: number;
40
+
41
+ /**
42
+ * A unique id representing the date from which this dump is obtained.
43
+ */
44
+ fromUniqueId: string;
45
+
46
+ /**
47
+ * A unique id representing the date until which this dump is obtained.
48
+ */
49
+ toUniqueId: string;
38
50
 
39
51
  /**
40
52
  * A list of updated files, keyed by file path. Its value is an object with two keys,
@@ -55,7 +67,12 @@ export type Dump = {
55
67
  deleted: Map<string, { oldPublicUrl: string | null; newPublicUrl: null }>;
56
68
 
57
69
  /**
58
- * Optional execution time taken by the dump, in milliseconds.
70
+ * The diff used to generate this dump.
59
71
  */
60
- execTimeMs?: number;
72
+ diff: Diff;
73
+ };
74
+
75
+ export type DumpMetadata = {
76
+ current: string;
77
+ dumps: Dump[];
61
78
  };