@simplysm/sd-cli 12.8.22 → 12.9.1

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 (95) hide show
  1. package/dist/entry/sd-cli-ai-command.js +2 -1
  2. package/dist/entry/sd-cli-ai-command.js.map +1 -1
  3. package/dist/entry/sd-cli-cordova.d.ts +1 -1
  4. package/dist/entry/sd-cli-cordova.js +1 -1
  5. package/dist/entry/sd-cli-cordova.js.map +1 -1
  6. package/dist/entry/sd-cli-electron.d.ts +6 -6
  7. package/dist/entry/sd-cli-electron.js +15 -9
  8. package/dist/entry/sd-cli-electron.js.map +1 -1
  9. package/dist/entry/sd-cli-local-update.d.ts +5 -5
  10. package/dist/entry/sd-cli-local-update.js +8 -12
  11. package/dist/entry/sd-cli-local-update.js.map +1 -1
  12. package/dist/entry/sd-cli-project.d.ts +11 -11
  13. package/dist/entry/sd-cli-project.js +11 -14
  14. package/dist/entry/sd-cli-project.js.map +1 -1
  15. package/dist/entry/utils/loadProjConfAsync.d.ts +5 -0
  16. package/dist/entry/utils/loadProjConfAsync.js +8 -0
  17. package/dist/entry/utils/loadProjConfAsync.js.map +1 -0
  18. package/dist/pkg-builders/client/sd-client.build-runner.js +1 -1
  19. package/dist/pkg-builders/client/sd-client.build-runner.js.map +1 -1
  20. package/dist/pkg-builders/client/sd-ng.bundler-context.d.ts +6 -5
  21. package/dist/pkg-builders/client/sd-ng.bundler-context.js +6 -6
  22. package/dist/pkg-builders/client/sd-ng.bundler-context.js.map +1 -1
  23. package/dist/pkg-builders/client/sd-ng.bundler.d.ts +13 -13
  24. package/dist/pkg-builders/client/sd-ng.bundler.js.map +1 -1
  25. package/dist/pkg-builders/client/sd-ng.plugin-creator.js +4 -88
  26. package/dist/pkg-builders/client/sd-ng.plugin-creator.js.map +1 -1
  27. package/dist/pkg-builders/lib/sd-js-lib.build-runner.js.map +1 -1
  28. package/dist/pkg-builders/lib/sd-ts-lib.build-runner.d.ts +1 -1
  29. package/dist/pkg-builders/lib/sd-ts-lib.build-runner.js.map +1 -1
  30. package/dist/pkg-builders/lib/sd-ts-lib.builder.js.map +1 -1
  31. package/dist/pkg-builders/sd-multi.build-runner.d.ts +4 -0
  32. package/dist/pkg-builders/sd-multi.build-runner.js +33 -25
  33. package/dist/pkg-builders/sd-multi.build-runner.js.map +1 -1
  34. package/dist/pkg-builders/server/sd-server.build-runner.js.map +1 -1
  35. package/dist/pkg-builders/server/sd-server.bundler.d.ts +6 -2
  36. package/dist/pkg-builders/server/sd-server.bundler.js +18 -19
  37. package/dist/pkg-builders/server/sd-server.bundler.js.map +1 -1
  38. package/dist/sd-cli/vitest.config.d.ts +2 -0
  39. package/dist/sd-cli/vitest.config.js +15 -0
  40. package/dist/sd-cli/vitest.config.js.map +1 -0
  41. package/dist/sd-cli.js +7 -36
  42. package/dist/sd-cli.js.map +1 -1
  43. package/dist/ts-compiler/sd-dependency-analyzer.d.ts +8 -0
  44. package/dist/ts-compiler/sd-dependency-analyzer.js +244 -0
  45. package/dist/ts-compiler/sd-dependency-analyzer.js.map +1 -0
  46. package/dist/ts-compiler/sd-dependency-cache.d.ts +27 -0
  47. package/dist/ts-compiler/sd-dependency-cache.js +232 -0
  48. package/dist/ts-compiler/sd-dependency-cache.js.map +1 -0
  49. package/dist/ts-compiler/sd-ts-compiler.d.ts +7 -10
  50. package/dist/ts-compiler/sd-ts-compiler.js +102 -228
  51. package/dist/ts-compiler/sd-ts-compiler.js.map +1 -1
  52. package/dist/types/worker.types.d.ts +19 -0
  53. package/dist/utils/sd-cli-performance-time.d.ts +2 -1
  54. package/dist/utils/sd-cli-performance-time.js +9 -9
  55. package/dist/utils/sd-cli-performance-time.js.map +1 -1
  56. package/dist/workers/style-bundler.worker.d.ts +1 -0
  57. package/dist/workers/style-bundler.worker.js +56 -0
  58. package/dist/workers/style-bundler.worker.js.map +1 -0
  59. package/package.json +10 -10
  60. package/src/entry/sd-cli-ai-command.ts +2 -1
  61. package/src/entry/sd-cli-cordova.ts +5 -5
  62. package/src/entry/sd-cli-electron.ts +54 -23
  63. package/src/entry/sd-cli-local-update.ts +14 -29
  64. package/src/entry/sd-cli-project.ts +24 -41
  65. package/src/entry/utils/loadProjConfAsync.ts +12 -0
  66. package/src/pkg-builders/client/sd-client.build-runner.ts +7 -7
  67. package/src/pkg-builders/client/sd-ng.bundler-context.ts +15 -12
  68. package/src/pkg-builders/client/sd-ng.bundler.ts +16 -16
  69. package/src/pkg-builders/client/sd-ng.plugin-creator.ts +5 -94
  70. package/src/pkg-builders/lib/sd-js-lib.build-runner.ts +6 -6
  71. package/src/pkg-builders/lib/sd-ts-lib.build-runner.ts +7 -7
  72. package/src/pkg-builders/lib/sd-ts-lib.builder.ts +1 -1
  73. package/src/pkg-builders/sd-multi.build-runner.ts +54 -39
  74. package/src/pkg-builders/server/sd-server.build-runner.ts +6 -6
  75. package/src/pkg-builders/server/sd-server.bundler.ts +26 -28
  76. package/src/sd-cli.ts +7 -36
  77. package/src/ts-compiler/sd-dependency-analyzer.ts +312 -0
  78. package/src/ts-compiler/sd-dependency-cache.ts +328 -0
  79. package/src/ts-compiler/sd-ts-compiler.ts +161 -302
  80. package/src/types/worker.types.ts +17 -0
  81. package/src/utils/sd-cli-performance-time.ts +9 -9
  82. package/src/workers/style-bundler.worker.ts +70 -0
  83. package/tests/deps/sd-dependency-analyzer.spec.ts +272 -0
  84. package/tests/deps/sd-dependency-cache.spec.ts +144 -0
  85. package/tsconfig.json +1 -1
  86. package/tsconfig.test.json +8 -0
  87. package/vitest.config.ts +15 -0
  88. package/dist/index.d.ts +0 -34
  89. package/dist/index.js +0 -35
  90. package/dist/index.js.map +0 -1
  91. package/dist/ts-compiler/sd-ts-dependency-analyzer.d.ts +0 -6
  92. package/dist/ts-compiler/sd-ts-dependency-analyzer.js +0 -141
  93. package/dist/ts-compiler/sd-ts-dependency-analyzer.js.map +0 -1
  94. package/src/index.ts +0 -34
  95. package/src/ts-compiler/sd-ts-dependency-analyzer.ts +0 -185
@@ -0,0 +1,328 @@
1
+ import { TNormPath } from "@simplysm/sd-core-node";
2
+
3
+ export class SdDependencyCache {
4
+ private _exportCache = new Map<
5
+ /* fileNPath: */ TNormPath,
6
+ /* exportSymbolSet: */ Set<string>
7
+ >();
8
+
9
+ private _importCache = new Map<
10
+ /* fileNPath: */ TNormPath,
11
+ Map<
12
+ /* targetNPath: */ TNormPath,
13
+ /* targetSymbolSet: */ Set<string> | 0
14
+ >
15
+ >();
16
+
17
+ private _reexportCache = new Map<
18
+ /* fileNPath: */ TNormPath,
19
+ Map<
20
+ /* targetNPath: */ TNormPath,
21
+ /* targetSymbolInfos: */ {
22
+ importSymbol: string;
23
+ exportSymbol: string;
24
+ }[] | 0
25
+ >
26
+ >();
27
+
28
+ private _revDepCache = new Map<
29
+ /* targetNPath: */ TNormPath,
30
+ Map<
31
+ /* fileNPath: */ TNormPath,
32
+ /* exportSymbolSet: */ Set<string> | 0 // fileNPath입장에선 import, targetNPath입장에선 export
33
+ >
34
+ >();
35
+
36
+ private _collectedCache = new Set<TNormPath>();
37
+
38
+ getFiles(): Set<TNormPath> {
39
+ return new Set<TNormPath>([
40
+ ...this._collectedCache.keys(),
41
+ ...this._revDepCache.keys(),
42
+ ]);
43
+ }
44
+
45
+ addCollected(fileNPath: TNormPath) {
46
+ this._collectedCache.add(fileNPath);
47
+ }
48
+
49
+ hasCollected(fileNPath: TNormPath) {
50
+ return this._collectedCache.has(fileNPath);
51
+ }
52
+
53
+ // export const ...
54
+ // export function/class/interface A ...
55
+ addExport(fileNPath: TNormPath, exportSymbol: string) {
56
+ const exportSymbolSet = this._exportCache.getOrCreate(fileNPath, new Set());
57
+ exportSymbolSet.add(exportSymbol);
58
+ }
59
+
60
+ // import * from "..."
61
+ // import ... from "..."
62
+ // import(...)
63
+ // require(...)
64
+ addImport(fileNPath: TNormPath, targetNPath: TNormPath, targetSymbol: string | 0) {
65
+ const importTargetMap = this._importCache.getOrCreate(fileNPath, new Map());
66
+ if (targetSymbol === 0) {
67
+ importTargetMap.set(targetNPath, 0);
68
+ this._addRevDep(targetNPath, fileNPath, 0);
69
+ }
70
+ else {
71
+ const importTargetSymbolSet = importTargetMap.getOrCreate(targetNPath, new Set());
72
+ if (importTargetSymbolSet === 0) {
73
+ return;
74
+ }
75
+
76
+ importTargetSymbolSet.add(targetSymbol);
77
+ this._addRevDep(targetNPath, fileNPath, targetSymbol);
78
+ }
79
+ }
80
+
81
+ // export * from '...'
82
+ // export { A as B } from '...'
83
+ //
84
+ // exoprt/import에 자동등록하진 않음.
85
+ // 차후 계산시 모든 캐시가 사용되므로,
86
+ // 이 클래스를 사용하는 곳에서는 따로따로 입력하면됨
87
+ addReexport(
88
+ fileNPath: TNormPath,
89
+ targetNPath: TNormPath,
90
+ targetSymbolInfo: { importSymbol: string, exportSymbol: string } | 0,
91
+ ) {
92
+ const reexportTargetMap = this._reexportCache.getOrCreate(fileNPath, new Map());
93
+ if (targetSymbolInfo === 0) {
94
+ reexportTargetMap.set(targetNPath, 0);
95
+ this._addRevDep(targetNPath, fileNPath, 0);
96
+ }
97
+ else {
98
+ const reexportTargetSymbolInfos = reexportTargetMap.getOrCreate(targetNPath, []);
99
+ if (reexportTargetSymbolInfos === 0) {
100
+ return;
101
+ }
102
+
103
+ if (
104
+ !reexportTargetSymbolInfos.some(item =>
105
+ item.importSymbol === targetSymbolInfo.importSymbol &&
106
+ item.exportSymbol === targetSymbolInfo.exportSymbol,
107
+ )
108
+ ) {
109
+ reexportTargetSymbolInfos.push(targetSymbolInfo);
110
+ this._addRevDep(targetNPath, fileNPath, targetSymbolInfo.importSymbol);
111
+ }
112
+ }
113
+ }
114
+
115
+ private _addRevDep(targetNPath: TNormPath, fileNPath: TNormPath, exportSymbol: string | 0) {
116
+ const revDepInfoMap = this._revDepCache.getOrCreate(targetNPath, new Map());
117
+ if (exportSymbol === 0) {
118
+ revDepInfoMap.set(fileNPath, exportSymbol);
119
+ }
120
+ else {
121
+ const exportSymbolSet = revDepInfoMap.getOrCreate(fileNPath, new Set());
122
+ if (exportSymbolSet === 0) {
123
+ return;
124
+ }
125
+
126
+ exportSymbolSet.add(exportSymbol);
127
+ }
128
+ }
129
+
130
+ getAffectedFileSet(modifiedNPathSet: Set<TNormPath>): Set<TNormPath> {
131
+ const visited = new Set<string>();
132
+
133
+ const result = new Set<TNormPath>(modifiedNPathSet);
134
+
135
+ const queue: { fileNPath: TNormPath, exportSymbol: string | undefined }[] = [];
136
+
137
+ const enqueue = (fileNPath: TNormPath, exportSymbol: string | undefined) => {
138
+ const key = `${fileNPath}#${exportSymbol}`;
139
+ if (!visited.has(key)) {
140
+ visited.add(key);
141
+ queue.push({ fileNPath, exportSymbol });
142
+ }
143
+ };
144
+
145
+ for (const modifiedNPath of modifiedNPathSet) {
146
+ const exportSymbols = this._getExportSymbols(modifiedNPath);
147
+ if (exportSymbols.size === 0) {
148
+ enqueue(modifiedNPath, undefined);
149
+ }
150
+ else {
151
+ for (const symbol of exportSymbols) {
152
+ enqueue(modifiedNPath, symbol);
153
+ }
154
+ }
155
+ }
156
+
157
+ while (queue.length > 0) {
158
+ const curr = queue.shift()!;
159
+
160
+ /*const key = curr.fileNPath + "#" + curr.exportSymbol;
161
+ if (visited.has(key)) continue;
162
+ visited.add(key);*/
163
+
164
+ const revDepInfoMap = this._revDepCache.get(curr.fileNPath);
165
+ if (!revDepInfoMap) continue;
166
+
167
+ for (const [revDepFileNPath, revDepInfo] of revDepInfoMap) {
168
+ if (curr.exportSymbol != null) {
169
+ // curr의 export를 토대로 revDep이 사용하고 있는지 체크
170
+ // curr.exportSymbol 와 revDev의 importSymbol은 같다
171
+ const hasImportSymbol = revDepInfo === 0 || revDepInfo.has(curr.exportSymbol);
172
+ if (hasImportSymbol) {
173
+ result.add(revDepFileNPath);
174
+
175
+ // 하위 Deps를 queue에 넣기전 export명칭 변환 (이름을 변경한 reexport일 경우 필요)
176
+ const exportSymbol = this._convertImportSymbolToExportSymbol(
177
+ revDepFileNPath,
178
+ curr.fileNPath,
179
+ curr.exportSymbol, // revdep의 importSymbol
180
+ );
181
+ enqueue(revDepFileNPath, exportSymbol);
182
+ }
183
+ }
184
+ else { // Resource
185
+ result.add(revDepFileNPath);
186
+ }
187
+ }
188
+ }
189
+
190
+ return result;
191
+ }
192
+
193
+ invalidates(fileNPathSet: Set<TNormPath>) {
194
+ const affectedFiles = this.getAffectedFileSet(fileNPathSet);
195
+
196
+ for (const fileNPath of affectedFiles) {
197
+ this._exportCache.delete(fileNPath);
198
+ this._importCache.delete(fileNPath);
199
+ this._reexportCache.delete(fileNPath);
200
+ this._collectedCache.delete(fileNPath);
201
+ this._revDepCache.delete(fileNPath); // ← 자기 자신이 key인 경우도 정리
202
+ }
203
+
204
+ // _revDepCache는 역방향으로 순회
205
+ for (const [targetNPath, infoMap] of this._revDepCache) {
206
+ for (const fileNPath of affectedFiles) {
207
+ infoMap.delete(fileNPath);
208
+ }
209
+
210
+ if (infoMap.size === 0) {
211
+ this._revDepCache.delete(targetNPath);
212
+ }
213
+ }
214
+ }
215
+
216
+ private _convertImportSymbolToExportSymbol(
217
+ fileNPath: TNormPath,
218
+ targetNPath: TNormPath,
219
+ importSymbol: string,
220
+ ) {
221
+ const symbolInfos = this._reexportCache.get(fileNPath)?.get(targetNPath);
222
+ if (symbolInfos != null && symbolInfos !== 0 && symbolInfos.length > 0) {
223
+ const symbolInfo = symbolInfos.single(item => item.importSymbol === importSymbol);
224
+ if (symbolInfo) {
225
+ return symbolInfo.exportSymbol;
226
+ }
227
+ }
228
+
229
+ return importSymbol;
230
+ }
231
+
232
+ private _getExportSymbols(fileNPath: TNormPath): Set<string> {
233
+ const result = new Set<string>();
234
+
235
+ const set = this._exportCache.get(fileNPath);
236
+ if (set) {
237
+ result.adds(...set);
238
+ }
239
+
240
+ const map = this._reexportCache.get(fileNPath);
241
+ if (map) {
242
+ for (const [key, val] of map) {
243
+ if (val === 0) {
244
+ result.adds(...this._getExportSymbols(key));
245
+ }
246
+ else {
247
+ result.adds(...val.map(item => item.exportSymbol));
248
+ }
249
+ }
250
+ }
251
+
252
+ return result;
253
+ }
254
+
255
+ // ---
256
+
257
+ getAffectedFileTree(modifiedNPathSet: Set<TNormPath>): ISdAffectedFileTreeNode[] {
258
+ const visited = new Set<string>(); // 순환 방지용: file#symbol
259
+ const nodeMap = new Map<string, ISdAffectedFileTreeNode>(); // 중복 노드 캐시
260
+
261
+ const buildTree = (
262
+ fileNPath: TNormPath,
263
+ exportSymbol: string | undefined
264
+ ): ISdAffectedFileTreeNode => {
265
+ const key = `${fileNPath}#${exportSymbol ?? "*"}`;
266
+
267
+ // 동일 노드가 이미 만들어졌다면 재사용
268
+ if (nodeMap.has(key)) return nodeMap.get(key)!;
269
+
270
+ // 방문 기록
271
+ visited.add(key);
272
+
273
+ // 노드 생성 및 캐싱
274
+ const node: ISdAffectedFileTreeNode = {
275
+ fileNPath,
276
+ children: []
277
+ };
278
+ nodeMap.set(key, node);
279
+
280
+ const revDepInfoMap = this._revDepCache.get(fileNPath);
281
+ if (!revDepInfoMap) return node;
282
+
283
+ for (const [revDepFileNPath, revDepInfo] of revDepInfoMap.entries()) {
284
+ const hasImportSymbol =
285
+ exportSymbol == null || revDepInfo === 0 || revDepInfo.has(exportSymbol);
286
+ if (!hasImportSymbol) continue;
287
+
288
+ const nextExportSymbol = exportSymbol != null
289
+ ? this._convertImportSymbolToExportSymbol(
290
+ revDepFileNPath,
291
+ fileNPath,
292
+ exportSymbol
293
+ )
294
+ : undefined;
295
+
296
+ const childKey = `${revDepFileNPath}#${nextExportSymbol ?? "*"}`;
297
+ if (visited.has(childKey)) continue; // 순환 방지
298
+
299
+ const childNode = buildTree(revDepFileNPath, nextExportSymbol);
300
+ node.children.push(childNode);
301
+ }
302
+
303
+ return node;
304
+ };
305
+
306
+ const result: ISdAffectedFileTreeNode[] = [];
307
+
308
+ for (const modifiedNPath of modifiedNPathSet) {
309
+ const exportSymbols = this._getExportSymbols(modifiedNPath);
310
+ if (exportSymbols.size === 0) {
311
+ const rootNode = buildTree(modifiedNPath, undefined);
312
+ result.push(rootNode);
313
+ } else {
314
+ for (const symbol of exportSymbols) {
315
+ const rootNode = buildTree(modifiedNPath, symbol);
316
+ result.push(rootNode);
317
+ }
318
+ }
319
+ }
320
+
321
+ return result;
322
+ }
323
+ }
324
+
325
+ export interface ISdAffectedFileTreeNode {
326
+ fileNPath: TNormPath;
327
+ children: ISdAffectedFileTreeNode[];
328
+ }