@akanjs/cli 1.0.7-canary.2 → 1.0.7-canary.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.
- package/cjs/index.js +24 -11
- package/cjs/src/guidelines/modelStore/modelStore.instruction.md +2 -7
- package/cjs/src/templates/lib/__lib/lib.constant.js +1 -2
- package/cjs/src/templates/lib/__lib/lib.dictionary.js +1 -2
- package/esm/index.js +24 -11
- package/esm/src/guidelines/modelStore/modelStore.instruction.md +2 -7
- package/esm/src/templates/lib/__lib/lib.constant.js +1 -2
- package/esm/src/templates/lib/__lib/lib.dictionary.js +1 -2
- package/package.json +1 -1
- package/src/guidelines/modelStore/modelStore.instruction.md +2 -7
package/cjs/index.js
CHANGED
|
@@ -1480,6 +1480,7 @@ var AppInfo = class _AppInfo extends ScanInfo {
|
|
|
1480
1480
|
type = "app";
|
|
1481
1481
|
exec;
|
|
1482
1482
|
akanConfig;
|
|
1483
|
+
libDeps;
|
|
1483
1484
|
static appInfos = /* @__PURE__ */ new Map();
|
|
1484
1485
|
static async fromExecutor(exec2, options = {}) {
|
|
1485
1486
|
const existingAppInfo = this.appInfos.get(exec2.name);
|
|
@@ -1493,24 +1494,41 @@ var AppInfo = class _AppInfo extends ScanInfo {
|
|
|
1493
1494
|
LibInfo.libInfos.set(libName, await LibInfo.fromExecutor(libExecutor));
|
|
1494
1495
|
})
|
|
1495
1496
|
);
|
|
1496
|
-
const
|
|
1497
|
+
const libDeps = await this.#getAllLibDeps(exec2, scanResult.libDeps);
|
|
1498
|
+
const appInfo = new _AppInfo(exec2, scanResult, libDeps);
|
|
1497
1499
|
this.appInfos.set(exec2.name, appInfo);
|
|
1498
1500
|
return appInfo;
|
|
1499
1501
|
}
|
|
1500
|
-
constructor(exec2, scanResult) {
|
|
1502
|
+
constructor(exec2, scanResult, libDeps) {
|
|
1501
1503
|
super(scanResult);
|
|
1502
1504
|
this.exec = exec2;
|
|
1503
1505
|
this.akanConfig = scanResult.akanConfig;
|
|
1506
|
+
this.libDeps = libDeps;
|
|
1504
1507
|
}
|
|
1505
1508
|
getScanResult() {
|
|
1506
1509
|
return this.scanResult;
|
|
1507
1510
|
}
|
|
1511
|
+
static async #getAllLibDeps(exec2, libDeps, libSet = /* @__PURE__ */ new Set()) {
|
|
1512
|
+
await Promise.all(
|
|
1513
|
+
libDeps.map(async (libName) => {
|
|
1514
|
+
if (libSet.has(libName))
|
|
1515
|
+
return;
|
|
1516
|
+
libSet.add(libName);
|
|
1517
|
+
const libExecutor = LibExecutor.from(exec2, libName);
|
|
1518
|
+
const libInfo = await LibInfo.fromExecutor(libExecutor);
|
|
1519
|
+
const libScanResult = libInfo.getScanResult();
|
|
1520
|
+
if (libScanResult.libDeps.length > 0)
|
|
1521
|
+
await this.#getAllLibDeps(exec2, libScanResult.libDeps, libSet);
|
|
1522
|
+
})
|
|
1523
|
+
);
|
|
1524
|
+
return [...libSet];
|
|
1525
|
+
}
|
|
1508
1526
|
#sortedLibs = null;
|
|
1509
1527
|
#getSortedLibs() {
|
|
1510
1528
|
if (this.#sortedLibs)
|
|
1511
1529
|
return this.#sortedLibs;
|
|
1512
1530
|
const libIndices = LibInfo.getSortedLibIndices();
|
|
1513
|
-
this.#sortedLibs = this.
|
|
1531
|
+
this.#sortedLibs = this.libDeps.sort((libNameA, libNameB) => {
|
|
1514
1532
|
const indexA = libIndices.get(libNameA);
|
|
1515
1533
|
const indexB = libIndices.get(libNameB);
|
|
1516
1534
|
if (indexA === void 0 || indexB === void 0)
|
|
@@ -1522,12 +1540,6 @@ var AppInfo = class _AppInfo extends ScanInfo {
|
|
|
1522
1540
|
getLibs() {
|
|
1523
1541
|
return this.#getSortedLibs();
|
|
1524
1542
|
}
|
|
1525
|
-
getLibInfo(libName) {
|
|
1526
|
-
const libSet = new Set(this.#getSortedLibs());
|
|
1527
|
-
if (!libSet.has(libName))
|
|
1528
|
-
throw new Error(`LibInfo is invalid: ${libName}`);
|
|
1529
|
-
return LibInfo.libInfos.get(libName);
|
|
1530
|
-
}
|
|
1531
1543
|
getLibInfos() {
|
|
1532
1544
|
return new Map(
|
|
1533
1545
|
this.#getSortedLibs().map((libName) => {
|
|
@@ -2170,7 +2182,7 @@ var Executor = class _Executor {
|
|
|
2170
2182
|
}, dict = {}, options = {}) {
|
|
2171
2183
|
if (targetPath.endsWith(".js") || targetPath.endsWith(".jsx")) {
|
|
2172
2184
|
const getContent = await import(templatePath);
|
|
2173
|
-
const result = getContent.default(scanInfo ?? null, dict, options);
|
|
2185
|
+
const result = await getContent.default(scanInfo ?? null, dict, options);
|
|
2174
2186
|
if (result === null)
|
|
2175
2187
|
return null;
|
|
2176
2188
|
const filename = typeof result === "object" ? result.filename : import_path4.default.basename(targetPath).replace(".js", ".ts");
|
|
@@ -2619,8 +2631,9 @@ var SysExecutor = class extends Executor {
|
|
|
2619
2631
|
const scanInfo = this.type === "app" ? await AppInfo.fromExecutor(this) : await LibInfo.fromExecutor(this);
|
|
2620
2632
|
const sysContantFiles = await this.getConstantFiles();
|
|
2621
2633
|
const sysScalarConstantFiles = await this.getScalarConstantFiles();
|
|
2634
|
+
const libDeps = scanInfo.getLibs();
|
|
2622
2635
|
const libConstantFiles = await Promise.all(
|
|
2623
|
-
|
|
2636
|
+
libDeps.map(async (lib) => [
|
|
2624
2637
|
...await LibExecutor.from(this, lib).getConstantFiles(),
|
|
2625
2638
|
...await LibExecutor.from(this, lib).getScalarConstantFiles()
|
|
2626
2639
|
])
|
|
@@ -35,7 +35,7 @@ Model stores follow a consistent architecture pattern:
|
|
|
35
35
|
```typescript
|
|
36
36
|
import { stateOf, Store } from "@akanjs/store";
|
|
37
37
|
import * as cnst from "../cnst";
|
|
38
|
-
import { fetch } from "../
|
|
38
|
+
import { fetch } from "../useServer";
|
|
39
39
|
|
|
40
40
|
export class ProductStore extends stateOf(fetch.productGql, {
|
|
41
41
|
// Custom state properties
|
|
@@ -437,19 +437,16 @@ initProductChat(productId: string) {
|
|
|
437
437
|
## Best Practices
|
|
438
438
|
|
|
439
439
|
1. **Naming Conventions**:
|
|
440
|
-
|
|
441
440
|
- Use `modelList{Context}` for slice names (e.g., `productListByCategory`)
|
|
442
441
|
- Use camelCase for state properties
|
|
443
442
|
- Use action verbs for method names
|
|
444
443
|
|
|
445
444
|
2. **State Management**:
|
|
446
|
-
|
|
447
445
|
- Keep UI state (loading, selected items) in the store
|
|
448
446
|
- Use `this.pick()` for accessing multiple properties
|
|
449
447
|
- Create new references for objects/arrays when updating
|
|
450
448
|
|
|
451
449
|
3. **Performance**:
|
|
452
|
-
|
|
453
450
|
- Use selective subscriptions in components:
|
|
454
451
|
```typescript
|
|
455
452
|
// Subscribe to specific state properties
|
|
@@ -459,13 +456,11 @@ initProductChat(productId: string) {
|
|
|
459
456
|
- Clean up subscriptions when components unmount
|
|
460
457
|
|
|
461
458
|
4. **Error Handling**:
|
|
462
|
-
|
|
463
459
|
- Use the `@Toast` decorator for user notifications
|
|
464
460
|
- Always reset loading states in finally blocks
|
|
465
461
|
- Implement retry logic for critical operations
|
|
466
462
|
|
|
467
463
|
5. **Testing**:
|
|
468
|
-
|
|
469
464
|
- Mock stores with initial state for unit tests
|
|
470
465
|
|
|
471
466
|
```typescript
|
|
@@ -485,7 +480,7 @@ initProductChat(productId: string) {
|
|
|
485
480
|
```typescript
|
|
486
481
|
import { stateOf, Store, Toast } from "@akanjs/store";
|
|
487
482
|
import * as cnst from "../cnst";
|
|
488
|
-
import { fetch } from "../
|
|
483
|
+
import { fetch } from "../useServer";
|
|
489
484
|
import { msg } from "../msg";
|
|
490
485
|
|
|
491
486
|
export class ProductStore extends stateOf(fetch.productGql, {
|
|
@@ -26,8 +26,7 @@ var capitalize = (str) => str.charAt(0).toUpperCase() + str.slice(1);
|
|
|
26
26
|
function getContent(scanInfo, dict = {}) {
|
|
27
27
|
if (!scanInfo)
|
|
28
28
|
return null;
|
|
29
|
-
const
|
|
30
|
-
const libs = scanResult.libDeps;
|
|
29
|
+
const libs = scanInfo.getLibs();
|
|
31
30
|
const libInfos = scanInfo.getLibInfos();
|
|
32
31
|
const extendedModels = Object.fromEntries(
|
|
33
32
|
[...scanInfo.file.constant.databases].map(
|
|
@@ -25,8 +25,7 @@ module.exports = __toCommonJS(lib_dictionary_exports);
|
|
|
25
25
|
function getContent(scanInfo, dict = {}) {
|
|
26
26
|
if (!scanInfo)
|
|
27
27
|
return null;
|
|
28
|
-
const
|
|
29
|
-
const libs = scanResult.libDeps;
|
|
28
|
+
const libs = scanInfo.getLibs();
|
|
30
29
|
const libInfos = scanInfo.getLibInfos();
|
|
31
30
|
const extendedModels = Object.fromEntries(
|
|
32
31
|
[...scanInfo.file.dictionary.databases].map(
|
package/esm/index.js
CHANGED
|
@@ -1459,6 +1459,7 @@ var AppInfo = class _AppInfo extends ScanInfo {
|
|
|
1459
1459
|
type = "app";
|
|
1460
1460
|
exec;
|
|
1461
1461
|
akanConfig;
|
|
1462
|
+
libDeps;
|
|
1462
1463
|
static appInfos = /* @__PURE__ */ new Map();
|
|
1463
1464
|
static async fromExecutor(exec2, options = {}) {
|
|
1464
1465
|
const existingAppInfo = this.appInfos.get(exec2.name);
|
|
@@ -1472,24 +1473,41 @@ var AppInfo = class _AppInfo extends ScanInfo {
|
|
|
1472
1473
|
LibInfo.libInfos.set(libName, await LibInfo.fromExecutor(libExecutor));
|
|
1473
1474
|
})
|
|
1474
1475
|
);
|
|
1475
|
-
const
|
|
1476
|
+
const libDeps = await this.#getAllLibDeps(exec2, scanResult.libDeps);
|
|
1477
|
+
const appInfo = new _AppInfo(exec2, scanResult, libDeps);
|
|
1476
1478
|
this.appInfos.set(exec2.name, appInfo);
|
|
1477
1479
|
return appInfo;
|
|
1478
1480
|
}
|
|
1479
|
-
constructor(exec2, scanResult) {
|
|
1481
|
+
constructor(exec2, scanResult, libDeps) {
|
|
1480
1482
|
super(scanResult);
|
|
1481
1483
|
this.exec = exec2;
|
|
1482
1484
|
this.akanConfig = scanResult.akanConfig;
|
|
1485
|
+
this.libDeps = libDeps;
|
|
1483
1486
|
}
|
|
1484
1487
|
getScanResult() {
|
|
1485
1488
|
return this.scanResult;
|
|
1486
1489
|
}
|
|
1490
|
+
static async #getAllLibDeps(exec2, libDeps, libSet = /* @__PURE__ */ new Set()) {
|
|
1491
|
+
await Promise.all(
|
|
1492
|
+
libDeps.map(async (libName) => {
|
|
1493
|
+
if (libSet.has(libName))
|
|
1494
|
+
return;
|
|
1495
|
+
libSet.add(libName);
|
|
1496
|
+
const libExecutor = LibExecutor.from(exec2, libName);
|
|
1497
|
+
const libInfo = await LibInfo.fromExecutor(libExecutor);
|
|
1498
|
+
const libScanResult = libInfo.getScanResult();
|
|
1499
|
+
if (libScanResult.libDeps.length > 0)
|
|
1500
|
+
await this.#getAllLibDeps(exec2, libScanResult.libDeps, libSet);
|
|
1501
|
+
})
|
|
1502
|
+
);
|
|
1503
|
+
return [...libSet];
|
|
1504
|
+
}
|
|
1487
1505
|
#sortedLibs = null;
|
|
1488
1506
|
#getSortedLibs() {
|
|
1489
1507
|
if (this.#sortedLibs)
|
|
1490
1508
|
return this.#sortedLibs;
|
|
1491
1509
|
const libIndices = LibInfo.getSortedLibIndices();
|
|
1492
|
-
this.#sortedLibs = this.
|
|
1510
|
+
this.#sortedLibs = this.libDeps.sort((libNameA, libNameB) => {
|
|
1493
1511
|
const indexA = libIndices.get(libNameA);
|
|
1494
1512
|
const indexB = libIndices.get(libNameB);
|
|
1495
1513
|
if (indexA === void 0 || indexB === void 0)
|
|
@@ -1501,12 +1519,6 @@ var AppInfo = class _AppInfo extends ScanInfo {
|
|
|
1501
1519
|
getLibs() {
|
|
1502
1520
|
return this.#getSortedLibs();
|
|
1503
1521
|
}
|
|
1504
|
-
getLibInfo(libName) {
|
|
1505
|
-
const libSet = new Set(this.#getSortedLibs());
|
|
1506
|
-
if (!libSet.has(libName))
|
|
1507
|
-
throw new Error(`LibInfo is invalid: ${libName}`);
|
|
1508
|
-
return LibInfo.libInfos.get(libName);
|
|
1509
|
-
}
|
|
1510
1522
|
getLibInfos() {
|
|
1511
1523
|
return new Map(
|
|
1512
1524
|
this.#getSortedLibs().map((libName) => {
|
|
@@ -2148,7 +2160,7 @@ var Executor = class _Executor {
|
|
|
2148
2160
|
}, dict = {}, options = {}) {
|
|
2149
2161
|
if (targetPath.endsWith(".js") || targetPath.endsWith(".jsx")) {
|
|
2150
2162
|
const getContent = await import(templatePath);
|
|
2151
|
-
const result = getContent.default(scanInfo ?? null, dict, options);
|
|
2163
|
+
const result = await getContent.default(scanInfo ?? null, dict, options);
|
|
2152
2164
|
if (result === null)
|
|
2153
2165
|
return null;
|
|
2154
2166
|
const filename = typeof result === "object" ? result.filename : path7.basename(targetPath).replace(".js", ".ts");
|
|
@@ -2597,8 +2609,9 @@ var SysExecutor = class extends Executor {
|
|
|
2597
2609
|
const scanInfo = this.type === "app" ? await AppInfo.fromExecutor(this) : await LibInfo.fromExecutor(this);
|
|
2598
2610
|
const sysContantFiles = await this.getConstantFiles();
|
|
2599
2611
|
const sysScalarConstantFiles = await this.getScalarConstantFiles();
|
|
2612
|
+
const libDeps = scanInfo.getLibs();
|
|
2600
2613
|
const libConstantFiles = await Promise.all(
|
|
2601
|
-
|
|
2614
|
+
libDeps.map(async (lib) => [
|
|
2602
2615
|
...await LibExecutor.from(this, lib).getConstantFiles(),
|
|
2603
2616
|
...await LibExecutor.from(this, lib).getScalarConstantFiles()
|
|
2604
2617
|
])
|
|
@@ -35,7 +35,7 @@ Model stores follow a consistent architecture pattern:
|
|
|
35
35
|
```typescript
|
|
36
36
|
import { stateOf, Store } from "@akanjs/store";
|
|
37
37
|
import * as cnst from "../cnst";
|
|
38
|
-
import { fetch } from "../
|
|
38
|
+
import { fetch } from "../useServer";
|
|
39
39
|
|
|
40
40
|
export class ProductStore extends stateOf(fetch.productGql, {
|
|
41
41
|
// Custom state properties
|
|
@@ -437,19 +437,16 @@ initProductChat(productId: string) {
|
|
|
437
437
|
## Best Practices
|
|
438
438
|
|
|
439
439
|
1. **Naming Conventions**:
|
|
440
|
-
|
|
441
440
|
- Use `modelList{Context}` for slice names (e.g., `productListByCategory`)
|
|
442
441
|
- Use camelCase for state properties
|
|
443
442
|
- Use action verbs for method names
|
|
444
443
|
|
|
445
444
|
2. **State Management**:
|
|
446
|
-
|
|
447
445
|
- Keep UI state (loading, selected items) in the store
|
|
448
446
|
- Use `this.pick()` for accessing multiple properties
|
|
449
447
|
- Create new references for objects/arrays when updating
|
|
450
448
|
|
|
451
449
|
3. **Performance**:
|
|
452
|
-
|
|
453
450
|
- Use selective subscriptions in components:
|
|
454
451
|
```typescript
|
|
455
452
|
// Subscribe to specific state properties
|
|
@@ -459,13 +456,11 @@ initProductChat(productId: string) {
|
|
|
459
456
|
- Clean up subscriptions when components unmount
|
|
460
457
|
|
|
461
458
|
4. **Error Handling**:
|
|
462
|
-
|
|
463
459
|
- Use the `@Toast` decorator for user notifications
|
|
464
460
|
- Always reset loading states in finally blocks
|
|
465
461
|
- Implement retry logic for critical operations
|
|
466
462
|
|
|
467
463
|
5. **Testing**:
|
|
468
|
-
|
|
469
464
|
- Mock stores with initial state for unit tests
|
|
470
465
|
|
|
471
466
|
```typescript
|
|
@@ -485,7 +480,7 @@ initProductChat(productId: string) {
|
|
|
485
480
|
```typescript
|
|
486
481
|
import { stateOf, Store, Toast } from "@akanjs/store";
|
|
487
482
|
import * as cnst from "../cnst";
|
|
488
|
-
import { fetch } from "../
|
|
483
|
+
import { fetch } from "../useServer";
|
|
489
484
|
import { msg } from "../msg";
|
|
490
485
|
|
|
491
486
|
export class ProductStore extends stateOf(fetch.productGql, {
|
|
@@ -3,8 +3,7 @@ var capitalize = (str) => str.charAt(0).toUpperCase() + str.slice(1);
|
|
|
3
3
|
function getContent(scanInfo, dict = {}) {
|
|
4
4
|
if (!scanInfo)
|
|
5
5
|
return null;
|
|
6
|
-
const
|
|
7
|
-
const libs = scanResult.libDeps;
|
|
6
|
+
const libs = scanInfo.getLibs();
|
|
8
7
|
const libInfos = scanInfo.getLibInfos();
|
|
9
8
|
const extendedModels = Object.fromEntries(
|
|
10
9
|
[...scanInfo.file.constant.databases].map(
|
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
function getContent(scanInfo, dict = {}) {
|
|
3
3
|
if (!scanInfo)
|
|
4
4
|
return null;
|
|
5
|
-
const
|
|
6
|
-
const libs = scanResult.libDeps;
|
|
5
|
+
const libs = scanInfo.getLibs();
|
|
7
6
|
const libInfos = scanInfo.getLibInfos();
|
|
8
7
|
const extendedModels = Object.fromEntries(
|
|
9
8
|
[...scanInfo.file.dictionary.databases].map(
|
package/package.json
CHANGED
|
@@ -35,7 +35,7 @@ Model stores follow a consistent architecture pattern:
|
|
|
35
35
|
```typescript
|
|
36
36
|
import { stateOf, Store } from "@akanjs/store";
|
|
37
37
|
import * as cnst from "../cnst";
|
|
38
|
-
import { fetch } from "../
|
|
38
|
+
import { fetch } from "../useServer";
|
|
39
39
|
|
|
40
40
|
export class ProductStore extends stateOf(fetch.productGql, {
|
|
41
41
|
// Custom state properties
|
|
@@ -437,19 +437,16 @@ initProductChat(productId: string) {
|
|
|
437
437
|
## Best Practices
|
|
438
438
|
|
|
439
439
|
1. **Naming Conventions**:
|
|
440
|
-
|
|
441
440
|
- Use `modelList{Context}` for slice names (e.g., `productListByCategory`)
|
|
442
441
|
- Use camelCase for state properties
|
|
443
442
|
- Use action verbs for method names
|
|
444
443
|
|
|
445
444
|
2. **State Management**:
|
|
446
|
-
|
|
447
445
|
- Keep UI state (loading, selected items) in the store
|
|
448
446
|
- Use `this.pick()` for accessing multiple properties
|
|
449
447
|
- Create new references for objects/arrays when updating
|
|
450
448
|
|
|
451
449
|
3. **Performance**:
|
|
452
|
-
|
|
453
450
|
- Use selective subscriptions in components:
|
|
454
451
|
```typescript
|
|
455
452
|
// Subscribe to specific state properties
|
|
@@ -459,13 +456,11 @@ initProductChat(productId: string) {
|
|
|
459
456
|
- Clean up subscriptions when components unmount
|
|
460
457
|
|
|
461
458
|
4. **Error Handling**:
|
|
462
|
-
|
|
463
459
|
- Use the `@Toast` decorator for user notifications
|
|
464
460
|
- Always reset loading states in finally blocks
|
|
465
461
|
- Implement retry logic for critical operations
|
|
466
462
|
|
|
467
463
|
5. **Testing**:
|
|
468
|
-
|
|
469
464
|
- Mock stores with initial state for unit tests
|
|
470
465
|
|
|
471
466
|
```typescript
|
|
@@ -485,7 +480,7 @@ initProductChat(productId: string) {
|
|
|
485
480
|
```typescript
|
|
486
481
|
import { stateOf, Store, Toast } from "@akanjs/store";
|
|
487
482
|
import * as cnst from "../cnst";
|
|
488
|
-
import { fetch } from "../
|
|
483
|
+
import { fetch } from "../useServer";
|
|
489
484
|
import { msg } from "../msg";
|
|
490
485
|
|
|
491
486
|
export class ProductStore extends stateOf(fetch.productGql, {
|