@directive-run/knowledge 0.2.0 → 0.5.0
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/LICENSE +1 -1
- package/README.md +3 -3
- package/ai/ai-adapters.md +7 -7
- package/ai/ai-agents-streaming.md +8 -8
- package/ai/ai-budget-resilience.md +5 -5
- package/ai/ai-communication.md +1 -1
- package/ai/ai-guardrails-memory.md +7 -7
- package/ai/ai-mcp-rag.md +5 -5
- package/ai/ai-multi-agent.md +14 -14
- package/ai/ai-orchestrator.md +8 -8
- package/ai/ai-security.md +2 -2
- package/ai/ai-tasks.md +9 -9
- package/ai/ai-testing-evals.md +2 -2
- package/core/anti-patterns.md +39 -39
- package/core/constraints.md +15 -15
- package/core/core-patterns.md +9 -9
- package/core/error-boundaries.md +7 -7
- package/core/multi-module.md +16 -16
- package/core/naming.md +21 -21
- package/core/plugins.md +14 -14
- package/core/react-adapter.md +13 -13
- package/core/resolvers.md +14 -14
- package/core/schema-types.md +22 -22
- package/core/system-api.md +16 -16
- package/core/testing.md +5 -5
- package/core/time-travel.md +20 -20
- package/dist/index.cjs +6 -105
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +7 -97
- package/dist/index.js.map +1 -1
- package/examples/ab-testing.ts +18 -90
- package/examples/ai-checkpoint.ts +68 -87
- package/examples/ai-guardrails.ts +20 -70
- package/examples/auth-flow.ts +2 -2
- package/examples/batch-resolver.ts +19 -59
- package/examples/contact-form.ts +220 -69
- package/examples/counter.ts +77 -95
- package/examples/dashboard-loader.ts +38 -56
- package/examples/debounce-constraints.ts +0 -2
- package/examples/dynamic-modules.ts +17 -20
- package/examples/error-boundaries.ts +30 -81
- package/examples/form-wizard.ts +6 -6
- package/examples/newsletter.ts +24 -51
- package/examples/notifications.ts +24 -23
- package/examples/optimistic-updates.ts +36 -41
- package/examples/pagination.ts +2 -2
- package/examples/permissions.ts +22 -32
- package/examples/provider-routing.ts +26 -83
- package/examples/shopping-cart.ts +12 -12
- package/examples/sudoku.ts +60 -67
- package/examples/theme-locale.ts +4 -7
- package/examples/time-machine.ts +12 -90
- package/examples/topic-guard.ts +31 -39
- package/examples/url-sync.ts +8 -8
- package/examples/websocket.ts +5 -5
- package/package.json +3 -3
package/core/system-api.md
CHANGED
|
@@ -23,14 +23,14 @@ What do you want to do?
|
|
|
23
23
|
import { createSystem } from "@directive-run/core";
|
|
24
24
|
import { loggingPlugin, devtoolsPlugin } from "@directive-run/core/plugins";
|
|
25
25
|
|
|
26
|
-
// Single module
|
|
26
|
+
// Single module – direct access to facts/derive/events
|
|
27
27
|
const system = createSystem({
|
|
28
28
|
module: myModule,
|
|
29
29
|
plugins: [loggingPlugin(), devtoolsPlugin()],
|
|
30
30
|
debug: { timeTravel: true, maxSnapshots: 100 },
|
|
31
31
|
});
|
|
32
32
|
|
|
33
|
-
// Multi-module
|
|
33
|
+
// Multi-module – namespaced access
|
|
34
34
|
const system = createSystem({
|
|
35
35
|
modules: {
|
|
36
36
|
auth: authModule,
|
|
@@ -48,7 +48,7 @@ const system = createSystem({
|
|
|
48
48
|
system.facts.count = 5;
|
|
49
49
|
const val = system.facts.count;
|
|
50
50
|
|
|
51
|
-
// Multi-module
|
|
51
|
+
// Multi-module – access through module namespace
|
|
52
52
|
system.facts.auth.token = "abc123";
|
|
53
53
|
system.facts.cart.items = [];
|
|
54
54
|
const token = system.facts.auth.token;
|
|
@@ -107,7 +107,7 @@ unsub();
|
|
|
107
107
|
// Wait until a condition is true
|
|
108
108
|
await system.when((facts) => facts.phase === "done");
|
|
109
109
|
|
|
110
|
-
// With timeout
|
|
110
|
+
// With timeout – throws if condition not met in time
|
|
111
111
|
await system.when((facts) => facts.phase === "done", { timeout: 5000 });
|
|
112
112
|
```
|
|
113
113
|
|
|
@@ -140,7 +140,7 @@ const unsub = system.onSettledChange(() => {
|
|
|
140
140
|
const count = system.read("count");
|
|
141
141
|
const isLoading = system.read("isLoading");
|
|
142
142
|
|
|
143
|
-
// Multi-module
|
|
143
|
+
// Multi-module – use dot notation
|
|
144
144
|
const token = system.read("auth.token");
|
|
145
145
|
const total = system.read("cart.totalPrice");
|
|
146
146
|
```
|
|
@@ -184,13 +184,13 @@ const explanation = system.explain("req-123");
|
|
|
184
184
|
## Lifecycle
|
|
185
185
|
|
|
186
186
|
```typescript
|
|
187
|
-
// Start
|
|
187
|
+
// Start – begins constraint evaluation and reconciliation
|
|
188
188
|
system.start();
|
|
189
189
|
|
|
190
|
-
// Stop
|
|
190
|
+
// Stop – pauses evaluation, cancels inflight resolvers
|
|
191
191
|
system.stop();
|
|
192
192
|
|
|
193
|
-
// Destroy
|
|
193
|
+
// Destroy – cleans up all resources, subscriptions, plugins
|
|
194
194
|
system.destroy();
|
|
195
195
|
|
|
196
196
|
// Lifecycle order:
|
|
@@ -202,13 +202,13 @@ system.destroy();
|
|
|
202
202
|
## Constraint Control at Runtime
|
|
203
203
|
|
|
204
204
|
```typescript
|
|
205
|
-
// Disable a constraint
|
|
205
|
+
// Disable a constraint – it won't be evaluated
|
|
206
206
|
system.constraints.disable("fetchWhenReady");
|
|
207
207
|
|
|
208
208
|
// Check if disabled
|
|
209
209
|
system.constraints.isDisabled("fetchWhenReady"); // true
|
|
210
210
|
|
|
211
|
-
// Re-enable
|
|
211
|
+
// Re-enable – triggers re-evaluation on next cycle
|
|
212
212
|
system.constraints.enable("fetchWhenReady");
|
|
213
213
|
```
|
|
214
214
|
|
|
@@ -217,11 +217,11 @@ system.constraints.enable("fetchWhenReady");
|
|
|
217
217
|
### Reading facts before settling
|
|
218
218
|
|
|
219
219
|
```typescript
|
|
220
|
-
// WRONG
|
|
220
|
+
// WRONG – resolver hasn't completed, facts are stale
|
|
221
221
|
system.start();
|
|
222
222
|
console.log(system.facts.user); // null
|
|
223
223
|
|
|
224
|
-
// CORRECT
|
|
224
|
+
// CORRECT – wait for async resolution
|
|
225
225
|
system.start();
|
|
226
226
|
await system.settle();
|
|
227
227
|
console.log(system.facts.user); // { id: "1", name: "Alice" }
|
|
@@ -230,10 +230,10 @@ console.log(system.facts.user); // { id: "1", name: "Alice" }
|
|
|
230
230
|
### Casting facts/derivations unnecessarily
|
|
231
231
|
|
|
232
232
|
```typescript
|
|
233
|
-
// WRONG
|
|
233
|
+
// WRONG – the schema already provides types
|
|
234
234
|
const profile = system.facts.profile as ResourceState<Profile>;
|
|
235
235
|
|
|
236
|
-
// CORRECT
|
|
236
|
+
// CORRECT – types are inferred from the schema
|
|
237
237
|
const profile = system.facts.profile;
|
|
238
238
|
```
|
|
239
239
|
|
|
@@ -254,7 +254,7 @@ system.watch("phase", (val) => {
|
|
|
254
254
|
### Forgetting to destroy
|
|
255
255
|
|
|
256
256
|
```typescript
|
|
257
|
-
// WRONG
|
|
257
|
+
// WRONG – resources leak
|
|
258
258
|
function setupSystem() {
|
|
259
259
|
const system = createSystem({ module: myModule });
|
|
260
260
|
system.start();
|
|
@@ -262,7 +262,7 @@ function setupSystem() {
|
|
|
262
262
|
return system;
|
|
263
263
|
}
|
|
264
264
|
|
|
265
|
-
// CORRECT
|
|
265
|
+
// CORRECT – clean up when done
|
|
266
266
|
const system = createSystem({ module: myModule });
|
|
267
267
|
system.start();
|
|
268
268
|
// ... when finished:
|
package/core/testing.md
CHANGED
|
@@ -29,7 +29,7 @@ import {
|
|
|
29
29
|
assertRequirement,
|
|
30
30
|
} from "@directive-run/core/testing";
|
|
31
31
|
|
|
32
|
-
// Single module
|
|
32
|
+
// Single module – same API as createSystem, with testing defaults
|
|
33
33
|
// (time-travel off, no plugins, synchronous settling)
|
|
34
34
|
const system = createTestSystem(myModule);
|
|
35
35
|
|
|
@@ -220,12 +220,12 @@ it("processes intermediate state", async () => {
|
|
|
220
220
|
### Testing real resolvers instead of mocking
|
|
221
221
|
|
|
222
222
|
```typescript
|
|
223
|
-
// WRONG
|
|
223
|
+
// WRONG – tests hit real APIs, slow and flaky
|
|
224
224
|
const system = createTestSystem(myModule);
|
|
225
225
|
system.facts.needsFetch = true;
|
|
226
226
|
await system.settle(); // Makes real HTTP call
|
|
227
227
|
|
|
228
|
-
// CORRECT
|
|
228
|
+
// CORRECT – mock the resolver
|
|
229
229
|
const system = createTestSystem(myModule, {
|
|
230
230
|
mockResolvers: [mockResolver("FETCH", async (req, context) => {
|
|
231
231
|
context.facts.data = { mocked: true };
|
|
@@ -236,11 +236,11 @@ const system = createTestSystem(myModule, {
|
|
|
236
236
|
### Forgetting to settle before asserting async results
|
|
237
237
|
|
|
238
238
|
```typescript
|
|
239
|
-
// WRONG
|
|
239
|
+
// WRONG – resolver hasn't completed yet
|
|
240
240
|
system.facts.trigger = true;
|
|
241
241
|
assertFact(system, "result", "done"); // Fails!
|
|
242
242
|
|
|
243
|
-
// CORRECT
|
|
243
|
+
// CORRECT – wait for resolution
|
|
244
244
|
system.facts.trigger = true;
|
|
245
245
|
await system.settle();
|
|
246
246
|
assertFact(system, "result", "done");
|
package/core/time-travel.md
CHANGED
|
@@ -9,7 +9,7 @@ What's the use case?
|
|
|
9
9
|
├── Debugging during development → Yes, enable with maxSnapshots cap
|
|
10
10
|
├── Production app → No, disable for performance
|
|
11
11
|
├── Bug reproduction → Enable, use exportHistory() to share
|
|
12
|
-
├── Testing → Usually no
|
|
12
|
+
├── Testing → Usually no – use assertFact/assertDerivation instead
|
|
13
13
|
└── Demo / presentation → Yes, great for showing state changes
|
|
14
14
|
```
|
|
15
15
|
|
|
@@ -37,8 +37,8 @@ Access via `system.debug.timeTravel`:
|
|
|
37
37
|
const tt = system.debug.timeTravel;
|
|
38
38
|
|
|
39
39
|
// Navigation
|
|
40
|
-
tt.canUndo(); // boolean
|
|
41
|
-
tt.canRedo(); // boolean
|
|
40
|
+
tt.canUndo(); // boolean – is there a previous snapshot?
|
|
41
|
+
tt.canRedo(); // boolean – is there a next snapshot?
|
|
42
42
|
tt.undo(); // Restore previous snapshot
|
|
43
43
|
tt.redo(); // Restore next snapshot
|
|
44
44
|
|
|
@@ -48,10 +48,10 @@ tt.goToSnapshot(index); // Jump to a specific snapshot by index
|
|
|
48
48
|
|
|
49
49
|
// Each snapshot contains:
|
|
50
50
|
// {
|
|
51
|
-
// facts: { ... },
|
|
52
|
-
// timestamp: number,
|
|
53
|
-
// label?: string,
|
|
54
|
-
// changedKeys: string[],
|
|
51
|
+
// facts: { ... }, – full fact state at that point
|
|
52
|
+
// timestamp: number, – when the snapshot was taken
|
|
53
|
+
// label?: string, – optional label from changeset
|
|
54
|
+
// changedKeys: string[], – which facts changed
|
|
55
55
|
// }
|
|
56
56
|
```
|
|
57
57
|
|
|
@@ -94,12 +94,12 @@ Multiple fact mutations can be grouped into a single undoable unit.
|
|
|
94
94
|
```typescript
|
|
95
95
|
const tt = system.debug.timeTravel;
|
|
96
96
|
|
|
97
|
-
// Without changeset
|
|
97
|
+
// Without changeset – each mutation is a separate snapshot
|
|
98
98
|
system.facts.firstName = "Alice";
|
|
99
99
|
system.facts.lastName = "Smith";
|
|
100
100
|
// Two snapshots, two undos needed
|
|
101
101
|
|
|
102
|
-
// With changeset
|
|
102
|
+
// With changeset – grouped into one snapshot
|
|
103
103
|
tt.beginChangeset("Update user name");
|
|
104
104
|
system.facts.firstName = "Alice";
|
|
105
105
|
system.facts.lastName = "Smith";
|
|
@@ -120,12 +120,12 @@ Serialize the full snapshot history for bug reports or debugging.
|
|
|
120
120
|
```typescript
|
|
121
121
|
const tt = system.debug.timeTravel;
|
|
122
122
|
|
|
123
|
-
// Export
|
|
123
|
+
// Export – returns a serializable object
|
|
124
124
|
const historyData = tt.exportHistory();
|
|
125
125
|
// Send to server, save to file, attach to bug report
|
|
126
126
|
console.log(JSON.stringify(historyData));
|
|
127
127
|
|
|
128
|
-
// Import
|
|
128
|
+
// Import – restore history from exported data
|
|
129
129
|
tt.importHistory(historyData);
|
|
130
130
|
|
|
131
131
|
// Now you can step through the user's exact state sequence
|
|
@@ -159,10 +159,10 @@ console.log(system.facts); // State as of snapshot 3
|
|
|
159
159
|
Every fact mutation creates a snapshot. Cap the number to control memory:
|
|
160
160
|
|
|
161
161
|
```typescript
|
|
162
|
-
// Low memory
|
|
162
|
+
// Low memory – keeps last 20 snapshots, discards oldest
|
|
163
163
|
debug: { timeTravel: true, maxSnapshots: 20 },
|
|
164
164
|
|
|
165
|
-
// Development
|
|
165
|
+
// Development – generous cap for deep debugging
|
|
166
166
|
debug: { timeTravel: true, maxSnapshots: 500 },
|
|
167
167
|
|
|
168
168
|
// Default if not specified
|
|
@@ -176,13 +176,13 @@ When the cap is reached, the oldest snapshot is discarded (FIFO). Redo history b
|
|
|
176
176
|
### Enabling time-travel in production
|
|
177
177
|
|
|
178
178
|
```typescript
|
|
179
|
-
// WRONG
|
|
179
|
+
// WRONG – snapshots consume memory on every mutation
|
|
180
180
|
const system = createSystem({
|
|
181
181
|
module: myModule,
|
|
182
182
|
debug: { timeTravel: true },
|
|
183
183
|
});
|
|
184
184
|
|
|
185
|
-
// CORRECT
|
|
185
|
+
// CORRECT – gate on environment
|
|
186
186
|
const system = createSystem({
|
|
187
187
|
module: myModule,
|
|
188
188
|
debug: {
|
|
@@ -195,13 +195,13 @@ const system = createSystem({
|
|
|
195
195
|
### Forgetting to end a changeset
|
|
196
196
|
|
|
197
197
|
```typescript
|
|
198
|
-
// WRONG
|
|
198
|
+
// WRONG – changeset never closed, all subsequent mutations are grouped
|
|
199
199
|
tt.beginChangeset("update");
|
|
200
200
|
system.facts.name = "Alice";
|
|
201
201
|
// ... forgot endChangeset()
|
|
202
202
|
system.facts.unrelated = true; // Still part of the changeset!
|
|
203
203
|
|
|
204
|
-
// CORRECT
|
|
204
|
+
// CORRECT – always close changesets
|
|
205
205
|
tt.beginChangeset("update");
|
|
206
206
|
system.facts.name = "Alice";
|
|
207
207
|
tt.endChangeset();
|
|
@@ -210,11 +210,11 @@ tt.endChangeset();
|
|
|
210
210
|
### Accessing time-travel when disabled
|
|
211
211
|
|
|
212
212
|
```typescript
|
|
213
|
-
// WRONG
|
|
213
|
+
// WRONG – timeTravel not enabled, system.debug.timeTravel is null
|
|
214
214
|
const system = createSystem({ module: myModule });
|
|
215
215
|
system.debug.timeTravel.undo(); // TypeError!
|
|
216
216
|
|
|
217
|
-
// CORRECT
|
|
217
|
+
// CORRECT – check before using
|
|
218
218
|
const tt = system.debug.timeTravel;
|
|
219
219
|
if (tt) {
|
|
220
220
|
tt.undo();
|
|
@@ -230,7 +230,7 @@ const system = createSystem({
|
|
|
230
230
|
### No maxSnapshots cap with frequent mutations
|
|
231
231
|
|
|
232
232
|
```typescript
|
|
233
|
-
// WRONG
|
|
233
|
+
// WRONG – unbounded snapshots in a high-frequency update loop
|
|
234
234
|
debug: { timeTravel: true }, // Default cap is 50, which is fine
|
|
235
235
|
|
|
236
236
|
// Be explicit when mutation rate is high
|
package/dist/index.cjs
CHANGED
|
@@ -1,111 +1,12 @@
|
|
|
1
|
-
'use strict';
|
|
1
|
+
'use strict';var fs=require('fs'),path=require('path'),url=require('url');var _documentCurrentScript=typeof document!=='undefined'?document.currentScript:null;var h=path.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)))),g=path.resolve(h,"..");function s(n){let t=path.join(g,n);if(fs.existsSync(t))return t;let e=path.join(g,"..",n);return fs.existsSync(e)?e:t}var w=s("core"),A=s("ai"),y=s("examples"),R=s("api-skeleton.md"),r=null,i=null;function a(n,t){try{let e=fs.readdirSync(n).filter(o=>o.endsWith(".md")||o.endsWith(".ts"));for(let o of e){let m=o.replace(/\.(md|ts)$/,"");t.set(m,fs.readFileSync(path.join(n,o),"utf-8"));}}catch(e){if(e.code!=="ENOENT")throw e}}function u(){let n=new Map;a(w,n),a(A,n);try{n.set("api-skeleton",fs.readFileSync(R,"utf-8"));}catch{}return n}function f(){let n=new Map;return a(y,n),n}function _(n){return r||(r=u()),r.get(n)??""}function O(){return r||(r=u()),r}function S(n){return i||(i=f()),i.get(n)??""}function P(){return i||(i=f()),i}function T(n){return n.map(t=>_(t)).filter(Boolean).join(`
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
var path = require('path');
|
|
5
|
-
var url = require('url');
|
|
3
|
+
---
|
|
6
4
|
|
|
7
|
-
|
|
8
|
-
// src/index.ts
|
|
9
|
-
var __dirname$1 = path.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href))));
|
|
10
|
-
var PKG_ROOT = path.resolve(__dirname$1, "..");
|
|
11
|
-
function resolveAsset(name) {
|
|
12
|
-
const fromDist = path.join(PKG_ROOT, name);
|
|
13
|
-
if (fs.existsSync(fromDist)) {
|
|
14
|
-
return fromDist;
|
|
15
|
-
}
|
|
16
|
-
const fromSrc = path.join(PKG_ROOT, "..", name);
|
|
17
|
-
if (fs.existsSync(fromSrc)) {
|
|
18
|
-
return fromSrc;
|
|
19
|
-
}
|
|
20
|
-
return fromDist;
|
|
21
|
-
}
|
|
22
|
-
var CORE_DIR = resolveAsset("core");
|
|
23
|
-
var AI_DIR = resolveAsset("ai");
|
|
24
|
-
var EXAMPLES_DIR = resolveAsset("examples");
|
|
25
|
-
var API_SKELETON_PATH = resolveAsset("api-skeleton.md");
|
|
26
|
-
var knowledgeCache = null;
|
|
27
|
-
var exampleCache = null;
|
|
28
|
-
function loadDir(dir, map) {
|
|
29
|
-
try {
|
|
30
|
-
const files = fs.readdirSync(dir).filter(
|
|
31
|
-
(f) => f.endsWith(".md") || f.endsWith(".ts")
|
|
32
|
-
);
|
|
33
|
-
for (const file of files) {
|
|
34
|
-
const name = file.replace(/\.(md|ts)$/, "");
|
|
35
|
-
map.set(name, fs.readFileSync(path.join(dir, file), "utf-8"));
|
|
36
|
-
}
|
|
37
|
-
} catch (err) {
|
|
38
|
-
if (err.code !== "ENOENT") {
|
|
39
|
-
throw err;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
function loadAllKnowledge() {
|
|
44
|
-
const map = /* @__PURE__ */ new Map();
|
|
45
|
-
loadDir(CORE_DIR, map);
|
|
46
|
-
loadDir(AI_DIR, map);
|
|
47
|
-
try {
|
|
48
|
-
map.set("api-skeleton", fs.readFileSync(API_SKELETON_PATH, "utf-8"));
|
|
49
|
-
} catch {
|
|
50
|
-
}
|
|
51
|
-
return map;
|
|
52
|
-
}
|
|
53
|
-
function loadAllExamples() {
|
|
54
|
-
const map = /* @__PURE__ */ new Map();
|
|
55
|
-
loadDir(EXAMPLES_DIR, map);
|
|
56
|
-
return map;
|
|
57
|
-
}
|
|
58
|
-
function getKnowledge(name) {
|
|
59
|
-
if (!knowledgeCache) {
|
|
60
|
-
knowledgeCache = loadAllKnowledge();
|
|
61
|
-
}
|
|
62
|
-
return knowledgeCache.get(name) ?? "";
|
|
63
|
-
}
|
|
64
|
-
function getAllKnowledge() {
|
|
65
|
-
if (!knowledgeCache) {
|
|
66
|
-
knowledgeCache = loadAllKnowledge();
|
|
67
|
-
}
|
|
68
|
-
return knowledgeCache;
|
|
69
|
-
}
|
|
70
|
-
function getExample(name) {
|
|
71
|
-
if (!exampleCache) {
|
|
72
|
-
exampleCache = loadAllExamples();
|
|
73
|
-
}
|
|
74
|
-
return exampleCache.get(name) ?? "";
|
|
75
|
-
}
|
|
76
|
-
function getAllExamples() {
|
|
77
|
-
if (!exampleCache) {
|
|
78
|
-
exampleCache = loadAllExamples();
|
|
79
|
-
}
|
|
80
|
-
return exampleCache;
|
|
81
|
-
}
|
|
82
|
-
function getKnowledgeFiles(names) {
|
|
83
|
-
return names.map((name) => getKnowledge(name)).filter(Boolean).join("\n\n---\n\n");
|
|
84
|
-
}
|
|
85
|
-
function getExampleFiles(names) {
|
|
86
|
-
return names.map((name) => {
|
|
87
|
-
const content = getExample(name);
|
|
88
|
-
if (!content) {
|
|
89
|
-
return "";
|
|
90
|
-
}
|
|
91
|
-
return `### Example: ${name}
|
|
5
|
+
`)}function k(n){return n.map(t=>{let e=S(t);return e?`### Example: ${t}
|
|
92
6
|
|
|
93
7
|
\`\`\`typescript
|
|
94
|
-
${
|
|
95
|
-
|
|
96
|
-
}).filter(Boolean).join("\n\n");
|
|
97
|
-
}
|
|
98
|
-
function clearCache() {
|
|
99
|
-
knowledgeCache = null;
|
|
100
|
-
exampleCache = null;
|
|
101
|
-
}
|
|
8
|
+
${e}
|
|
9
|
+
\`\`\``:""}).filter(Boolean).join(`
|
|
102
10
|
|
|
103
|
-
exports.clearCache =
|
|
104
|
-
exports.getAllExamples = getAllExamples;
|
|
105
|
-
exports.getAllKnowledge = getAllKnowledge;
|
|
106
|
-
exports.getExample = getExample;
|
|
107
|
-
exports.getExampleFiles = getExampleFiles;
|
|
108
|
-
exports.getKnowledge = getKnowledge;
|
|
109
|
-
exports.getKnowledgeFiles = getKnowledgeFiles;
|
|
110
|
-
//# sourceMappingURL=index.cjs.map
|
|
11
|
+
`)}function v(){r=null,i=null;}exports.clearCache=v;exports.getAllExamples=P;exports.getAllKnowledge=O;exports.getExample=S;exports.getExampleFiles=k;exports.getKnowledge=_;exports.getKnowledgeFiles=T;//# sourceMappingURL=index.cjs.map
|
|
111
12
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"names":["__dirname","dirname","fileURLToPath","resolve","join","existsSync","readdirSync","readFileSync"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"names":["__dirname","dirname","fileURLToPath","PKG_ROOT","resolve","resolveAsset","name","fromDist","join","existsSync","fromSrc","CORE_DIR","AI_DIR","EXAMPLES_DIR","API_SKELETON_PATH","knowledgeCache","exampleCache","loadDir","dir","map","files","readdirSync","f","file","readFileSync","err","loadAllKnowledge","loadAllExamples","getKnowledge","getAllKnowledge","getExample","getAllExamples","getKnowledgeFiles","names","getExampleFiles","content","clearCache"],"mappings":"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","file":"index.cjs","sourcesContent":["import { existsSync, readFileSync, readdirSync } from \"node:fs\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\n// Resolve package root: works both in src/ (dev) and dist/ (bundled)\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst PKG_ROOT = resolve(__dirname, \"..\");\n\n/**\n * Resolve a path relative to the package root.\n * Tries dist-relative first (bundled), then src-relative (dev).\n */\nfunction resolveAsset(name: string): string {\n const fromDist = join(PKG_ROOT, name);\n if (existsSync(fromDist)) {\n return fromDist;\n }\n\n const fromSrc = join(PKG_ROOT, \"..\", name);\n if (existsSync(fromSrc)) {\n return fromSrc;\n }\n\n return fromDist; // default, will just return empty maps\n}\n\nconst CORE_DIR = resolveAsset(\"core\");\nconst AI_DIR = resolveAsset(\"ai\");\nconst EXAMPLES_DIR = resolveAsset(\"examples\");\nconst API_SKELETON_PATH = resolveAsset(\"api-skeleton.md\");\n\nlet knowledgeCache: Map<string, string> | null = null;\nlet exampleCache: Map<string, string> | null = null;\n\nfunction loadDir(dir: string, map: Map<string, string>): void {\n try {\n const files = readdirSync(dir).filter(\n (f) => f.endsWith(\".md\") || f.endsWith(\".ts\"),\n );\n for (const file of files) {\n const name = file.replace(/\\.(md|ts)$/, \"\");\n map.set(name, readFileSync(join(dir, file), \"utf-8\"));\n }\n } catch (err: unknown) {\n if ((err as NodeJS.ErrnoException).code !== \"ENOENT\") {\n throw err;\n }\n // directory does not exist — expected during tests or incomplete installs\n }\n}\n\nfunction loadAllKnowledge(): Map<string, string> {\n const map = new Map<string, string>();\n loadDir(CORE_DIR, map);\n loadDir(AI_DIR, map);\n\n // Include api-skeleton\n try {\n map.set(\"api-skeleton\", readFileSync(API_SKELETON_PATH, \"utf-8\"));\n } catch {\n // may not exist yet\n }\n\n return map;\n}\n\nfunction loadAllExamples(): Map<string, string> {\n const map = new Map<string, string>();\n loadDir(EXAMPLES_DIR, map);\n\n return map;\n}\n\nexport function getKnowledge(name: string): string {\n if (!knowledgeCache) {\n knowledgeCache = loadAllKnowledge();\n }\n\n return knowledgeCache.get(name) ?? \"\";\n}\n\nexport function getAllKnowledge(): ReadonlyMap<string, string> {\n if (!knowledgeCache) {\n knowledgeCache = loadAllKnowledge();\n }\n\n return knowledgeCache;\n}\n\nexport function getExample(name: string): string {\n if (!exampleCache) {\n exampleCache = loadAllExamples();\n }\n\n return exampleCache.get(name) ?? \"\";\n}\n\nexport function getAllExamples(): ReadonlyMap<string, string> {\n if (!exampleCache) {\n exampleCache = loadAllExamples();\n }\n\n return exampleCache;\n}\n\nexport function getKnowledgeFiles(names: string[]): string {\n return names\n .map((name) => getKnowledge(name))\n .filter(Boolean)\n .join(\"\\n\\n---\\n\\n\");\n}\n\nexport function getExampleFiles(names: string[]): string {\n return names\n .map((name) => {\n const content = getExample(name);\n if (!content) {\n return \"\";\n }\n\n return `### Example: ${name}\\n\\n\\`\\`\\`typescript\\n${content}\\n\\`\\`\\``;\n })\n .filter(Boolean)\n .join(\"\\n\\n\");\n}\n\n/** Clear cached knowledge and examples. Useful for dev/watch mode. */\nexport function clearCache(): void {\n knowledgeCache = null;\n exampleCache = null;\n}\n"]}
|
package/dist/index.js
CHANGED
|
@@ -1,102 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { dirname, resolve, join } from 'path';
|
|
3
|
-
import { fileURLToPath } from 'url';
|
|
1
|
+
import {existsSync,readFileSync,readdirSync}from'fs';import {dirname,resolve,join}from'path';import {fileURLToPath}from'url';var h=dirname(fileURLToPath(import.meta.url)),g=resolve(h,"..");function s(n){let t=join(g,n);if(existsSync(t))return t;let e=join(g,"..",n);return existsSync(e)?e:t}var w=s("core"),A=s("ai"),y=s("examples"),R=s("api-skeleton.md"),r=null,i=null;function a(n,t){try{let e=readdirSync(n).filter(o=>o.endsWith(".md")||o.endsWith(".ts"));for(let o of e){let m=o.replace(/\.(md|ts)$/,"");t.set(m,readFileSync(join(n,o),"utf-8"));}}catch(e){if(e.code!=="ENOENT")throw e}}function u(){let n=new Map;a(w,n),a(A,n);try{n.set("api-skeleton",readFileSync(R,"utf-8"));}catch{}return n}function f(){let n=new Map;return a(y,n),n}function _(n){return r||(r=u()),r.get(n)??""}function O(){return r||(r=u()),r}function S(n){return i||(i=f()),i.get(n)??""}function P(){return i||(i=f()),i}function T(n){return n.map(t=>_(t)).filter(Boolean).join(`
|
|
4
2
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
function resolveAsset(name) {
|
|
9
|
-
const fromDist = join(PKG_ROOT, name);
|
|
10
|
-
if (existsSync(fromDist)) {
|
|
11
|
-
return fromDist;
|
|
12
|
-
}
|
|
13
|
-
const fromSrc = join(PKG_ROOT, "..", name);
|
|
14
|
-
if (existsSync(fromSrc)) {
|
|
15
|
-
return fromSrc;
|
|
16
|
-
}
|
|
17
|
-
return fromDist;
|
|
18
|
-
}
|
|
19
|
-
var CORE_DIR = resolveAsset("core");
|
|
20
|
-
var AI_DIR = resolveAsset("ai");
|
|
21
|
-
var EXAMPLES_DIR = resolveAsset("examples");
|
|
22
|
-
var API_SKELETON_PATH = resolveAsset("api-skeleton.md");
|
|
23
|
-
var knowledgeCache = null;
|
|
24
|
-
var exampleCache = null;
|
|
25
|
-
function loadDir(dir, map) {
|
|
26
|
-
try {
|
|
27
|
-
const files = readdirSync(dir).filter(
|
|
28
|
-
(f) => f.endsWith(".md") || f.endsWith(".ts")
|
|
29
|
-
);
|
|
30
|
-
for (const file of files) {
|
|
31
|
-
const name = file.replace(/\.(md|ts)$/, "");
|
|
32
|
-
map.set(name, readFileSync(join(dir, file), "utf-8"));
|
|
33
|
-
}
|
|
34
|
-
} catch (err) {
|
|
35
|
-
if (err.code !== "ENOENT") {
|
|
36
|
-
throw err;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
function loadAllKnowledge() {
|
|
41
|
-
const map = /* @__PURE__ */ new Map();
|
|
42
|
-
loadDir(CORE_DIR, map);
|
|
43
|
-
loadDir(AI_DIR, map);
|
|
44
|
-
try {
|
|
45
|
-
map.set("api-skeleton", readFileSync(API_SKELETON_PATH, "utf-8"));
|
|
46
|
-
} catch {
|
|
47
|
-
}
|
|
48
|
-
return map;
|
|
49
|
-
}
|
|
50
|
-
function loadAllExamples() {
|
|
51
|
-
const map = /* @__PURE__ */ new Map();
|
|
52
|
-
loadDir(EXAMPLES_DIR, map);
|
|
53
|
-
return map;
|
|
54
|
-
}
|
|
55
|
-
function getKnowledge(name) {
|
|
56
|
-
if (!knowledgeCache) {
|
|
57
|
-
knowledgeCache = loadAllKnowledge();
|
|
58
|
-
}
|
|
59
|
-
return knowledgeCache.get(name) ?? "";
|
|
60
|
-
}
|
|
61
|
-
function getAllKnowledge() {
|
|
62
|
-
if (!knowledgeCache) {
|
|
63
|
-
knowledgeCache = loadAllKnowledge();
|
|
64
|
-
}
|
|
65
|
-
return knowledgeCache;
|
|
66
|
-
}
|
|
67
|
-
function getExample(name) {
|
|
68
|
-
if (!exampleCache) {
|
|
69
|
-
exampleCache = loadAllExamples();
|
|
70
|
-
}
|
|
71
|
-
return exampleCache.get(name) ?? "";
|
|
72
|
-
}
|
|
73
|
-
function getAllExamples() {
|
|
74
|
-
if (!exampleCache) {
|
|
75
|
-
exampleCache = loadAllExamples();
|
|
76
|
-
}
|
|
77
|
-
return exampleCache;
|
|
78
|
-
}
|
|
79
|
-
function getKnowledgeFiles(names) {
|
|
80
|
-
return names.map((name) => getKnowledge(name)).filter(Boolean).join("\n\n---\n\n");
|
|
81
|
-
}
|
|
82
|
-
function getExampleFiles(names) {
|
|
83
|
-
return names.map((name) => {
|
|
84
|
-
const content = getExample(name);
|
|
85
|
-
if (!content) {
|
|
86
|
-
return "";
|
|
87
|
-
}
|
|
88
|
-
return `### Example: ${name}
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
`)}function k(n){return n.map(t=>{let e=S(t);return e?`### Example: ${t}
|
|
89
6
|
|
|
90
7
|
\`\`\`typescript
|
|
91
|
-
${
|
|
92
|
-
|
|
93
|
-
}).filter(Boolean).join("\n\n");
|
|
94
|
-
}
|
|
95
|
-
function clearCache() {
|
|
96
|
-
knowledgeCache = null;
|
|
97
|
-
exampleCache = null;
|
|
98
|
-
}
|
|
8
|
+
${e}
|
|
9
|
+
\`\`\``:""}).filter(Boolean).join(`
|
|
99
10
|
|
|
100
|
-
|
|
101
|
-
//# sourceMappingURL=index.js.map
|
|
11
|
+
`)}function v(){r=null,i=null;}export{v as clearCache,P as getAllExamples,O as getAllKnowledge,S as getExample,k as getExampleFiles,_ as getKnowledge,T as getKnowledgeFiles};//# sourceMappingURL=index.js.map
|
|
102
12
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"names":["__dirname"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"names":["__dirname","dirname","fileURLToPath","PKG_ROOT","resolve","resolveAsset","name","fromDist","join","existsSync","fromSrc","CORE_DIR","AI_DIR","EXAMPLES_DIR","API_SKELETON_PATH","knowledgeCache","exampleCache","loadDir","dir","map","files","readdirSync","f","file","readFileSync","err","loadAllKnowledge","loadAllExamples","getKnowledge","getAllKnowledge","getExample","getAllExamples","getKnowledgeFiles","names","getExampleFiles","content","clearCache"],"mappings":"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","file":"index.js","sourcesContent":["import { existsSync, readFileSync, readdirSync } from \"node:fs\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\n// Resolve package root: works both in src/ (dev) and dist/ (bundled)\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst PKG_ROOT = resolve(__dirname, \"..\");\n\n/**\n * Resolve a path relative to the package root.\n * Tries dist-relative first (bundled), then src-relative (dev).\n */\nfunction resolveAsset(name: string): string {\n const fromDist = join(PKG_ROOT, name);\n if (existsSync(fromDist)) {\n return fromDist;\n }\n\n const fromSrc = join(PKG_ROOT, \"..\", name);\n if (existsSync(fromSrc)) {\n return fromSrc;\n }\n\n return fromDist; // default, will just return empty maps\n}\n\nconst CORE_DIR = resolveAsset(\"core\");\nconst AI_DIR = resolveAsset(\"ai\");\nconst EXAMPLES_DIR = resolveAsset(\"examples\");\nconst API_SKELETON_PATH = resolveAsset(\"api-skeleton.md\");\n\nlet knowledgeCache: Map<string, string> | null = null;\nlet exampleCache: Map<string, string> | null = null;\n\nfunction loadDir(dir: string, map: Map<string, string>): void {\n try {\n const files = readdirSync(dir).filter(\n (f) => f.endsWith(\".md\") || f.endsWith(\".ts\"),\n );\n for (const file of files) {\n const name = file.replace(/\\.(md|ts)$/, \"\");\n map.set(name, readFileSync(join(dir, file), \"utf-8\"));\n }\n } catch (err: unknown) {\n if ((err as NodeJS.ErrnoException).code !== \"ENOENT\") {\n throw err;\n }\n // directory does not exist — expected during tests or incomplete installs\n }\n}\n\nfunction loadAllKnowledge(): Map<string, string> {\n const map = new Map<string, string>();\n loadDir(CORE_DIR, map);\n loadDir(AI_DIR, map);\n\n // Include api-skeleton\n try {\n map.set(\"api-skeleton\", readFileSync(API_SKELETON_PATH, \"utf-8\"));\n } catch {\n // may not exist yet\n }\n\n return map;\n}\n\nfunction loadAllExamples(): Map<string, string> {\n const map = new Map<string, string>();\n loadDir(EXAMPLES_DIR, map);\n\n return map;\n}\n\nexport function getKnowledge(name: string): string {\n if (!knowledgeCache) {\n knowledgeCache = loadAllKnowledge();\n }\n\n return knowledgeCache.get(name) ?? \"\";\n}\n\nexport function getAllKnowledge(): ReadonlyMap<string, string> {\n if (!knowledgeCache) {\n knowledgeCache = loadAllKnowledge();\n }\n\n return knowledgeCache;\n}\n\nexport function getExample(name: string): string {\n if (!exampleCache) {\n exampleCache = loadAllExamples();\n }\n\n return exampleCache.get(name) ?? \"\";\n}\n\nexport function getAllExamples(): ReadonlyMap<string, string> {\n if (!exampleCache) {\n exampleCache = loadAllExamples();\n }\n\n return exampleCache;\n}\n\nexport function getKnowledgeFiles(names: string[]): string {\n return names\n .map((name) => getKnowledge(name))\n .filter(Boolean)\n .join(\"\\n\\n---\\n\\n\");\n}\n\nexport function getExampleFiles(names: string[]): string {\n return names\n .map((name) => {\n const content = getExample(name);\n if (!content) {\n return \"\";\n }\n\n return `### Example: ${name}\\n\\n\\`\\`\\`typescript\\n${content}\\n\\`\\`\\``;\n })\n .filter(Boolean)\n .join(\"\\n\\n\");\n}\n\n/** Clear cached knowledge and examples. Useful for dev/watch mode. */\nexport function clearCache(): void {\n knowledgeCache = null;\n exampleCache = null;\n}\n"]}
|