@_linked/core 0.0.1 → 1.0.0-next.20260211072341
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/CHANGELOG.md +62 -0
- package/LICENSE +1 -1
- package/README.md +1 -53
- package/package.json +17 -1
- package/.context/notes.md +0 -0
- package/.context/todos.md +0 -0
- package/AGENTS.md +0 -59
- package/docs/001-core-extraction.md +0 -305
- package/jest.config.js +0 -25
- package/scripts/dual-package.js +0 -25
- package/src/collections/CoreMap.ts +0 -127
- package/src/collections/CoreSet.ts +0 -171
- package/src/collections/ShapeSet.ts +0 -18
- package/src/index.ts +0 -88
- package/src/interfaces/ICoreIterable.ts +0 -35
- package/src/interfaces/IFileStore.ts +0 -28
- package/src/interfaces/IQuadStore.ts +0 -16
- package/src/interfaces/IQueryParser.ts +0 -51
- package/src/ontologies/lincd.ts +0 -25
- package/src/ontologies/npm.ts +0 -15
- package/src/ontologies/owl.ts +0 -26
- package/src/ontologies/rdf.ts +0 -32
- package/src/ontologies/rdfs.ts +0 -38
- package/src/ontologies/shacl.ts +0 -136
- package/src/ontologies/xsd.ts +0 -47
- package/src/package.ts +0 -11
- package/src/queries/CreateQuery.ts +0 -41
- package/src/queries/DeleteQuery.ts +0 -54
- package/src/queries/MutationQuery.ts +0 -287
- package/src/queries/QueryContext.ts +0 -41
- package/src/queries/QueryFactory.ts +0 -275
- package/src/queries/QueryParser.ts +0 -79
- package/src/queries/SelectQuery.ts +0 -2101
- package/src/queries/UpdateQuery.ts +0 -47
- package/src/shapes/List.ts +0 -52
- package/src/shapes/SHACL.ts +0 -653
- package/src/shapes/Shape.ts +0 -282
- package/src/test-helpers/query-fixtures.ts +0 -313
- package/src/tests/core-utils.test.ts +0 -286
- package/src/tests/metadata.test.ts +0 -65
- package/src/tests/query.test.ts +0 -599
- package/src/tests/query.types.test.ts +0 -606
- package/src/tests/store-routing.test.ts +0 -133
- package/src/utils/LinkedErrorLogging.ts +0 -25
- package/src/utils/LinkedFileStorage.ts +0 -75
- package/src/utils/LinkedStorage.ts +0 -120
- package/src/utils/NameSpace.ts +0 -5
- package/src/utils/NodeReference.ts +0 -16
- package/src/utils/Package.ts +0 -681
- package/src/utils/Prefix.ts +0 -108
- package/src/utils/ShapeClass.ts +0 -335
- package/src/utils/Types.ts +0 -19
- package/src/utils/URI.ts +0 -40
- package/src/utils/cached.ts +0 -53
- package/tsconfig-cjs.json +0 -8
- package/tsconfig-esm.json +0 -9
- package/tsconfig.json +0 -29
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 1.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- [#1](https://github.com/Semantu/linked/pull/1) [`0938ede`](https://github.com/Semantu/linked/commit/0938edec623e9d611767ae150b8d60270035ffeb) Thanks [@flyon](https://github.com/flyon)! - first major release
|
|
8
|
+
|
|
9
|
+
### 1.0.0 (from LINCD.js)
|
|
10
|
+
|
|
11
|
+
This is a rebranding + extraction release. It moves the core query/shape system into `@_linked/core` and removes RDF models and React-specific code.
|
|
12
|
+
|
|
13
|
+
Key changes:
|
|
14
|
+
|
|
15
|
+
- **New package name:** import from `@_linked/core` instead of `lincd`.
|
|
16
|
+
- **Node references everywhere:** use `NodeReferenceValue = {id: string}` everywhere. `NamedNode` does not exist in this package.
|
|
17
|
+
- **Before (LINCD.js):**
|
|
18
|
+
```typescript
|
|
19
|
+
import { NamedNode } from "lincd/models";
|
|
20
|
+
const name = NamedNode.getOrCreate("https://schema.org/name");
|
|
21
|
+
```
|
|
22
|
+
- **After (`@_linked/core`):**
|
|
23
|
+
```typescript
|
|
24
|
+
import { createNameSpace } from "@_linked/core/utils/NameSpace";
|
|
25
|
+
const schema = createNameSpace("https://schema.org/");
|
|
26
|
+
const name = schema("name"); // {id: 'https://schema.org/name'}
|
|
27
|
+
```
|
|
28
|
+
- **Decorator paths:** property decorators now require `NodeReferenceValue` paths (no strings, no `NamedNode`).
|
|
29
|
+
- **Before:**
|
|
30
|
+
```typescript
|
|
31
|
+
@literalProperty({path: foaf.name})
|
|
32
|
+
```
|
|
33
|
+
- **After:**
|
|
34
|
+
```typescript
|
|
35
|
+
const name = schema('name');
|
|
36
|
+
@literalProperty({path: name})
|
|
37
|
+
```
|
|
38
|
+
- **Target class and node kinds:** `targetClass`, `datatype`, `nodeKind`, etc. now take `NodeReferenceValue`.
|
|
39
|
+
- **Before:**
|
|
40
|
+
```typescript
|
|
41
|
+
static targetClass = foaf.Person; // NamedNode
|
|
42
|
+
```
|
|
43
|
+
- **After:**
|
|
44
|
+
```typescript
|
|
45
|
+
static targetClass = schema('Person'); // {id: string}
|
|
46
|
+
```
|
|
47
|
+
- **Query context:** context values are `NodeReferenceValue` (or QResults) instead of RDF nodes.
|
|
48
|
+
- **Before:**
|
|
49
|
+
```typescript
|
|
50
|
+
setQueryContext("user", NamedNode.getOrCreate(userId), Person);
|
|
51
|
+
```
|
|
52
|
+
- **After:**
|
|
53
|
+
```typescript
|
|
54
|
+
setQueryContext("user", { id: userId }, Person);
|
|
55
|
+
```
|
|
56
|
+
- **No RDF models in core:** `NamedNode`, `Literal`, `BlankNode`, `Quad`, `Graph`, and all RDF collections are not available in `@_linked/core`. Use a store package (e.g. `@_linked/rdf-mem-store`) if you need RDF models or quad-level access.
|
|
57
|
+
- **Shape instances:** shape classes no longer carry RDF nodes or instance graph APIs. Decorated accessors register SHACL metadata but do not implement runtime get/set behavior.
|
|
58
|
+
- **Query tracing:** query tracing is proxy-based (no `TestNode`/`TraceShape`).
|
|
59
|
+
- **SHACL metadata:** node/property shapes are plain JS objects (`QResult`), not RDF triples.
|
|
60
|
+
- **Package registration:** `linkedPackage` now stores package metadata as plain JS (`PackageMetadata`) and keeps legacy URI ids for compatibility.
|
|
61
|
+
- **Storage routing:** `LinkedStorage` routes queries to an `IQuadStore` implementation (e.g. `@_linked/rdf-mem-store`).
|
|
62
|
+
- **Imports updated:** ontology namespaces now return `NodeReferenceValue` objects, and decorators require `NodeReferenceValue` paths.
|
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -323,56 +323,4 @@ await Person.delete({id: 'https://my.app/node1'});
|
|
|
323
323
|
|
|
324
324
|
## Changelog
|
|
325
325
|
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
This is a rebranding + extraction release. It moves the core query/shape system into `@_linked/core` and removes RDF models and React-specific code.
|
|
329
|
-
|
|
330
|
-
Key changes:
|
|
331
|
-
- **New package name:** import from `@_linked/core` instead of `lincd`.
|
|
332
|
-
- **Node references everywhere:** use `NodeReferenceValue = {id: string}` everywhere. `NamedNode` does not exist in this package.
|
|
333
|
-
- **Before (LINCD.js):**
|
|
334
|
-
```typescript
|
|
335
|
-
import {NamedNode} from 'lincd/models';
|
|
336
|
-
const name = NamedNode.getOrCreate('https://schema.org/name');
|
|
337
|
-
```
|
|
338
|
-
- **After (`@_linked/core`):**
|
|
339
|
-
```typescript
|
|
340
|
-
import {createNameSpace} from '@_linked/core/utils/NameSpace';
|
|
341
|
-
const schema = createNameSpace('https://schema.org/');
|
|
342
|
-
const name = schema('name'); // {id: 'https://schema.org/name'}
|
|
343
|
-
```
|
|
344
|
-
- **Decorator paths:** property decorators now require `NodeReferenceValue` paths (no strings, no `NamedNode`).
|
|
345
|
-
- **Before:**
|
|
346
|
-
```typescript
|
|
347
|
-
@literalProperty({path: foaf.name})
|
|
348
|
-
```
|
|
349
|
-
- **After:**
|
|
350
|
-
```typescript
|
|
351
|
-
const name = schema('name');
|
|
352
|
-
@literalProperty({path: name})
|
|
353
|
-
```
|
|
354
|
-
- **Target class and node kinds:** `targetClass`, `datatype`, `nodeKind`, etc. now take `NodeReferenceValue`.
|
|
355
|
-
- **Before:**
|
|
356
|
-
```typescript
|
|
357
|
-
static targetClass = foaf.Person; // NamedNode
|
|
358
|
-
```
|
|
359
|
-
- **After:**
|
|
360
|
-
```typescript
|
|
361
|
-
static targetClass = schema('Person'); // {id: string}
|
|
362
|
-
```
|
|
363
|
-
- **Query context:** context values are `NodeReferenceValue` (or QResults) instead of RDF nodes.
|
|
364
|
-
- **Before:**
|
|
365
|
-
```typescript
|
|
366
|
-
setQueryContext('user', NamedNode.getOrCreate(userId), Person);
|
|
367
|
-
```
|
|
368
|
-
- **After:**
|
|
369
|
-
```typescript
|
|
370
|
-
setQueryContext('user', {id: userId}, Person);
|
|
371
|
-
```
|
|
372
|
-
- **No RDF models in core:** `NamedNode`, `Literal`, `BlankNode`, `Quad`, `Graph`, and all RDF collections are not available in `@_linked/core`. Use a store package (e.g. `@_linked/rdf-mem-store`) if you need RDF models or quad-level access.
|
|
373
|
-
- **Shape instances:** shape classes no longer carry RDF nodes or instance graph APIs. Decorated accessors register SHACL metadata but do not implement runtime get/set behavior.
|
|
374
|
-
- **Query tracing:** query tracing is proxy-based (no `TestNode`/`TraceShape`).
|
|
375
|
-
- **SHACL metadata:** node/property shapes are plain JS objects (`QResult`), not RDF triples.
|
|
376
|
-
- **Package registration:** `linkedPackage` now stores package metadata as plain JS (`PackageMetadata`) and keeps legacy URI ids for compatibility.
|
|
377
|
-
- **Storage routing:** `LinkedStorage` routes queries to an `IQuadStore` implementation (e.g. `@_linked/rdf-mem-store`).
|
|
378
|
-
- **Imports updated:** ontology namespaces now return `NodeReferenceValue` objects, and decorators require `NodeReferenceValue` paths.
|
|
326
|
+
See [CHANGELOG.md](./CHANGELOG.md).
|
package/package.json
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@_linked/core",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "1.0.0-next.20260211072341",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Linked.js core query and SHACL shape DSL (copy-then-prune baseline)",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/Semantu/linked.git"
|
|
9
|
+
},
|
|
6
10
|
"main": "lib/cjs/index.js",
|
|
7
11
|
"module": "lib/esm/index.js",
|
|
8
12
|
"exports": {
|
|
@@ -24,6 +28,16 @@
|
|
|
24
28
|
]
|
|
25
29
|
}
|
|
26
30
|
},
|
|
31
|
+
"publishConfig": {
|
|
32
|
+
"access": "public",
|
|
33
|
+
"provenance": true
|
|
34
|
+
},
|
|
35
|
+
"files": [
|
|
36
|
+
"lib",
|
|
37
|
+
"README.md",
|
|
38
|
+
"CHANGELOG.md",
|
|
39
|
+
"LICENSE"
|
|
40
|
+
],
|
|
27
41
|
"scripts": {
|
|
28
42
|
"build": "npx rimraf ./lib && npx tsc -p tsconfig-cjs.json && npx tsc -p tsconfig-esm.json && node ./scripts/dual-package.js",
|
|
29
43
|
"compile": "echo '💫 Compiling CJS' && npx tsc -p tsconfig-cjs.json && echo '💫 Compiling ESM' && npx tsc -p tsconfig-esm.json",
|
|
@@ -31,6 +45,8 @@
|
|
|
31
45
|
"test": "npx jest --config jest.config.js"
|
|
32
46
|
},
|
|
33
47
|
"devDependencies": {
|
|
48
|
+
"@changesets/changelog-github": "^0.5.2",
|
|
49
|
+
"@changesets/cli": "^2.29.8",
|
|
34
50
|
"@jest/globals": "^29.7.0",
|
|
35
51
|
"@types/jest": "^29.5.12",
|
|
36
52
|
"@types/node": "^20.12.7",
|
package/.context/notes.md
DELETED
|
File without changes
|
package/.context/todos.md
DELETED
|
File without changes
|
package/AGENTS.md
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
# AGENTS.md — @_linked/core repository
|
|
2
|
-
|
|
3
|
-
## Repository structure
|
|
4
|
-
|
|
5
|
-
Single-package repository for `@_linked/core` (query DSL, SHACL shape decorators, package registration, LinkedStorage). No internal package dependencies.
|
|
6
|
-
|
|
7
|
-
Tests: `npm test`
|
|
8
|
-
|
|
9
|
-
## Agent docs (`docs/`)
|
|
10
|
-
|
|
11
|
-
Files are numbered with a 3-digit prefix for ordering. Names should be explicit about contents (lowercase-dash format). Every file starts with YAML frontmatter:
|
|
12
|
-
|
|
13
|
-
```yaml
|
|
14
|
-
---
|
|
15
|
-
summary: One-line description of what this document covers
|
|
16
|
-
packages: [core, react]
|
|
17
|
-
---
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
```bash
|
|
21
|
-
ls docs/ # list all docs
|
|
22
|
-
head -4 docs/*.md # get summaries (or replace * with a specific file)
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
Each package also has a `README.md` with API docs and a `## Changelog` at the bottom.
|
|
26
|
-
|
|
27
|
-
## Planning and implementation workflow
|
|
28
|
-
|
|
29
|
-
### When to plan
|
|
30
|
-
|
|
31
|
-
Any task that changes package code requires a plan. Simple checks, info gathering, and discussions do not.
|
|
32
|
-
|
|
33
|
-
### Creating a plan
|
|
34
|
-
|
|
35
|
-
1. **Inspect the relevant code thoroughly** before writing anything. Read the source files, tests, and existing docs that relate to the task.
|
|
36
|
-
2. Create a new doc in `docs/` with the next 3-digit prefix (e.g. `005-add-filter-support.md`). Start with YAML frontmatter.
|
|
37
|
-
3. Write the plan with these sections:
|
|
38
|
-
- **Key considerations and choices** — tradeoffs, open questions, alternatives
|
|
39
|
-
- **Potential problems** — what could go wrong, edge cases
|
|
40
|
-
- **Phases** — ordered list of implementation steps. Each phase has a clear scope and describes how it will be validated. Small tasks: 1-2 phases. Larger tasks: more.
|
|
41
|
-
4. **Ask the user to review the plan before implementing.**
|
|
42
|
-
|
|
43
|
-
### Implementing phases
|
|
44
|
-
|
|
45
|
-
- **One commit per phase.** Include the plan doc update (marking the phase complete) in the same commit.
|
|
46
|
-
- **Every phase must be validated** — at minimum one relevant passing test.
|
|
47
|
-
- **After each phase, report to the user:**
|
|
48
|
-
- What was done
|
|
49
|
-
- Any deviations from the plan
|
|
50
|
-
- Problems encountered
|
|
51
|
-
- Validation results (pass/fail counts and what was tested)
|
|
52
|
-
- What you plan to do next
|
|
53
|
-
|
|
54
|
-
### Wrapping up
|
|
55
|
-
|
|
56
|
-
Before committing final changes or preparing a PR:
|
|
57
|
-
|
|
58
|
-
1. **Consolidate the plan doc** — collapse alternatives into the choices that were made, summarize implementation details and breaking changes, keep a brief problems section if relevant, remove anything redundant for future readers.
|
|
59
|
-
2. **Update `## Changelog`** in each affected package's `README.md` — user-facing entry covering behavior changes, new APIs, breaking changes, and migration steps.
|
|
@@ -1,305 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
summary: Extract @_linked/core from the LINCD monolith using copy-then-prune. Covers query DSL, SHACL shapes, package registration, and LinkedStorage. Documents prior failed attempts and why copy-then-prune was chosen.
|
|
3
|
-
packages: [core]
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# @_linked/core — package extraction plan (copy-then-prune)
|
|
7
|
-
|
|
8
|
-
## Context
|
|
9
|
-
|
|
10
|
-
The original LINCD repository (`src/` at the repo root) is a monolithic codebase that bundles everything together: RDF models, an in-memory quad store, SHACL shape definitions, a query DSL, React component linking, package registration, and more.
|
|
11
|
-
|
|
12
|
-
We are splitting this monolith into three separate packages under `rebrand/`:
|
|
13
|
-
|
|
14
|
-
1. **`@_linked/core`** (this plan) — The query DSL, SHACL shape decorators/metadata, and package registration. No React. No RDF models.
|
|
15
|
-
2. **`@_linked/memstore`** — RDF node models (NamedNode, Literal, BlankNode, Quad), the in-memory quad store, and LocalQueryResolver. An earlier version exists on branch `origin/codex/implement-additional-query-tests-in-linked-js` as `rebrand/linked-mem-store`.
|
|
16
|
-
3. **`@_linked/react`** — React components, hooks, and `linkedComponent`/`linkedSetComponent` linking helpers.
|
|
17
|
-
|
|
18
|
-
### Prior attempts & lessons learned
|
|
19
|
-
|
|
20
|
-
Two prior attempts at extracting the core package exist in this repo. Both contain useful reference code but neither produced a shippable result:
|
|
21
|
-
|
|
22
|
-
- **`rebrand/linked-js`** (local + more developed version on branch `origin/codex/implement-additional-query-tests-in-linked-js`) — a clean-room rewrite. This version solved many of the hard design problems: `NodeReferenceValue = {id: string}` instead of `NamedNode`, Proxy-based query tracing instead of `TestNode`, a plain-JS `NodeShape` class, a `ShapeClass` registry, shared `test-helpers/query-fixtures.ts`, and full CRUD query support with type inference. **What went wrong:** building from scratch meant that the complex type inference chain (`QueryResponseToResultType` and related types) had to be recreated manually, which proved error-prone. Getting the full type inference working again from scratch was too difficult.
|
|
23
|
-
|
|
24
|
-
- **`rebrand/linked-js2`** — copy-then-prune with a full copy of root `src/`. Had working query-object tests and type inference tests, and was on a good trajectory. **What went wrong:** the agent session got stuck and some of the last work was not committed. When the branch was cloned to continue, the tests no longer passed — defeating the whole point of maintaining a green baseline at all times. The work itself was sound, but the loss of the green state made it unrecoverable.
|
|
25
|
-
|
|
26
|
-
Both folders are kept as reference for the approach and design patterns. However, we should not copy large chunks from them wholesale — the goal is to prune the existing code step by step, using the earlier attempts only as inspiration for what the target state looks like.
|
|
27
|
-
|
|
28
|
-
### Why copy-then-prune (done carefully) is the right approach
|
|
29
|
-
|
|
30
|
-
The most critical aspect of this codebase is the **query result type inference chain**. When a developer writes:
|
|
31
|
-
|
|
32
|
-
```typescript
|
|
33
|
-
const result = await Person.select(p => ({name: p.name, friend: p.bestFriend}));
|
|
34
|
-
// ^-- result type is inferred as QResult<Person, {name: string, friend: Person}>[]
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
TypeScript infers the full result type through a chain of conditional types: `SelectQueryFactory<S, ResponseType>` → `QueryResponseToResultType<ResponseType, ShapeType>` → `GetQueryObjectResultType` → `QResult<Shape, Object>`. This inference chain spans `SelectQuery.ts`, `QueryFactory.ts`, and `Shape.ts`. It is the core value of the library and it is fragile — a single wrong type change can collapse the entire chain to `unknown` or `never`.
|
|
38
|
-
|
|
39
|
-
Building from scratch (linked-js) made it hard to reproduce this chain. The linked-js2 attempt was on a good trajectory but lost its green baseline when the agent session got stuck and uncommitted work was lost.
|
|
40
|
-
|
|
41
|
-
**This time we prune one small piece at a time**, committing after each successful step, and verifying after each step that:
|
|
42
|
-
1. The build compiles.
|
|
43
|
-
2. The tests pass.
|
|
44
|
-
3. The type inference tests (`query.types.test.ts`) still validate that inferred types are correct.
|
|
45
|
-
|
|
46
|
-
### Shared test fixtures & query factories
|
|
47
|
-
|
|
48
|
-
The test setup exports query factories — functions or objects that invoke the same queries used by both test files. This is also designed so that `@_linked/memstore` can later import the same query factories to test actual query results against the in-memory store, without duplicating the queries. One source of truth for what is being tested.
|
|
49
|
-
|
|
50
|
-
The codex branch version of `rebrand/linked-js` introduced a `test-helpers/query-fixtures.ts` that exports reusable `Person`, `Pet`, `Dog` shape classes and property path constants. This pattern should be adopted and extended with the full set of query factories.
|
|
51
|
-
|
|
52
|
-
### Methodology
|
|
53
|
-
|
|
54
|
-
1. Start from a fresh copy of root `src/` in a new `rebrand/core/` folder, reusing the root `node_modules`.
|
|
55
|
-
2. Incrementally remove pieces that don't belong in `@_linked/core`.
|
|
56
|
-
3. After each removal step, verify that build compiles and tests pass — **including type inference tests**.
|
|
57
|
-
4. **Commit after each successful step.** A lesson from the linked-js2 attempt: uncommitted work can be lost. Every green state should be committed so we can always recover.
|
|
58
|
-
5. **Tests may only be changed with explicit user approval.** If a test fails after a pruning step, ask the user for feedback rather than silently changing what is validated.
|
|
59
|
-
6. Use both `rebrand/linked-js` and `rebrand/linked-js2` as reference for inspiration, but don't copy large chunks wholesale — prune the existing files toward the target step by step.
|
|
60
|
-
7. **Update this plan after every step.** When a phase or sub-step is completed and committed, mark it as done in this file (with the commit hash) and commit the plan update. This plan is the single source of truth for progress.
|
|
61
|
-
|
|
62
|
-
### What belongs in `@_linked/core`
|
|
63
|
-
|
|
64
|
-
- **Query DSL** — `SelectQuery`, `CreateQuery`, `UpdateQuery`, `DeleteQuery`, `MutationQuery`, `QueryFactory`, `QueryParser`, `QueryContext`.
|
|
65
|
-
- **SHACL shape decorators** — `@linkedShape`, `@literalProperty`, `@objectProperty`, `@linkedProperty` and the underlying `NodeShape`/`PropertyShape` metadata classes that track which SHACL shapes and properties exist in consuming code.
|
|
66
|
-
- **Package registration** — `Package.ts` (`linkedPackage()`, `registerPackageExport()`, `getPackageShape()`, `@linkedUtil`, `@linkedOntology`).
|
|
67
|
-
- **Shape base class** — `Shape.ts` (static query methods and metadata; no instance RDF behavior).
|
|
68
|
-
- **Supporting utilities** — `ShapeClass` (registry: find a shape class from a node shape ID), `LinkedStorage` (interface/routing only, no concrete store), `Types`, and any other utilities required by the above.
|
|
69
|
-
- **Interfaces** — `IShape`, `IQueryParser`, `IQuadStore` (interface only), `IGraphObject`, `IGraphObjectSet`, `ICoreIterable`, etc.
|
|
70
|
-
|
|
71
|
-
### What does NOT belong in `@_linked/core`
|
|
72
|
-
|
|
73
|
-
- **React** — No `linkedComponent`, `linkedSetComponent`, `LinkedComponentClass`, `Hooks.ts`, or any React imports. These belong in `@_linked/react`.
|
|
74
|
-
- **RDF node models** — No `NamedNode`, `Literal`, `BlankNode`, `Quad`, `DefaultGraph`, `Datafactory.ts`, `models.ts`. These belong in `@_linked/memstore`.
|
|
75
|
-
- **In-memory store** — No `LocalQueryResolver`, no concrete quad store implementation. These belong in `@_linked/memstore`.
|
|
76
|
-
- **Node/Quad collections** — No `NodeSet`, `NodeMap`, `QuadSet`, `QuadMap`, `QuadArray`, `NodeURIMappings`, `NodeValuesSet`. These depend on RDF models and belong in `@_linked/memstore`.
|
|
77
|
-
- **CSS** — No styling resources.
|
|
78
|
-
- **Ontology data files** — Ontology definitions that instantiate RDF nodes belong in `@_linked/memstore` or a separate ontology package. The core package may retain ontology *interfaces* if needed.
|
|
79
|
-
|
|
80
|
-
---
|
|
81
|
-
|
|
82
|
-
## Decisions
|
|
83
|
-
|
|
84
|
-
These are the resolved design decisions for how `@_linked/core` handles the transition away from RDF models.
|
|
85
|
-
|
|
86
|
-
### Phase 1 setup choices (2026-02-04)
|
|
87
|
-
|
|
88
|
-
- **Config approach:** Use the `rebrand/linked-js2` pattern for build/test configs (ts-jest running from `src/tests`, `testMatch` in `jest.config.js`, and tsconfig paths that point to the root `node_modules`). This avoids a separate build step to run tests and keeps the setup minimal.
|
|
89
|
-
- **Package name:** Set `package.json` name to `@_linked/core` immediately.
|
|
90
|
-
- **Test files:** Use `.ts` (no TSX).
|
|
91
|
-
- **Test environment:** Use `testEnvironment: "node"` (no React involved).
|
|
92
|
-
- **Sub-step 1.2 QueryCaptureStore:** Implement `select`, `create`, `update`, and `delete` from the start.
|
|
93
|
-
- **Copy baseline:** Copy the entire root `src/` into `rebrand/core/src/` first, then prune later.
|
|
94
|
-
- **Reporting rule:** After every run, report back with: what was done, any problems encountered, changes made that were not in the plan, and how the work was validated (including explicit test results like # passed/# failed and what was tested).
|
|
95
|
-
- **Phase commit rule:** After each phase, commit your changes and update this plan to indicate progress. If you later need to revert changes, either commit on top or reset to a previous commit if more applicable.
|
|
96
|
-
- **Single-commit rule:** One commit per phase/sub-step. Update this plan to mark completion *before* committing so the work + plan change are in the same commit. If you add the commit hash afterward, that plan-only tweak can wait and be included with the next phase’s commit (no extra immediate commit needed).
|
|
97
|
-
- **Validation rule:** Every phase or sub-step must be validated. For test-related steps, validation requires at least the relevant tests to pass (e.g., Sub-step 1.2 requires the single query test to pass).
|
|
98
|
-
- **Next-step rule:** In each report, briefly state what the next step entails and include the exact title of the next sub-step.
|
|
99
|
-
|
|
100
|
-
### NodeReferenceValue replaces NamedNode
|
|
101
|
-
|
|
102
|
-
The type `NodeReferenceValue = {id: string}` already exists in `QueryFactory.ts`. Everywhere the current code uses `NamedNode`, we replace it with `NodeReferenceValue` (or import it under a shorter alias if convenient). This is a plain object with an `id` key holding the URI.
|
|
103
|
-
|
|
104
|
-
Config parameters accept `string | NodeReferenceValue` and internally normalize:
|
|
105
|
-
|
|
106
|
-
```typescript
|
|
107
|
-
const toNodeReference = (value: string | NodeReferenceValue): NodeReferenceValue => {
|
|
108
|
-
return typeof value === 'string' ? {id: value} : value;
|
|
109
|
-
};
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
The codex branch already uses this pattern (under the name `NodeRef`). In tests and fixtures, paths can be defined as plain strings since the decorator config accepts `string | NodeReferenceValue`.
|
|
113
|
-
|
|
114
|
-
In `@_linked/memstore`, `NamedNode` will satisfy `NodeReferenceValue` since NamedNode already has an `id` property (its URI). This means memstore code can pass NamedNode objects wherever `NodeReferenceValue` is expected.
|
|
115
|
-
|
|
116
|
-
### Shape instances no longer point to a NamedNode
|
|
117
|
-
|
|
118
|
-
The current `Shape` instances hold a reference to a `NamedNode` (the RDF node they represent). In `@_linked/core`, this is removed. Shape becomes a purely static construct: `static shape: NodeShape`, `static queryParser: IQueryParser`, and static methods (`select()`, `create()`, `update()`, `delete()`).
|
|
119
|
-
|
|
120
|
-
Instance methods that operate on RDF data (`getOne()`, `getAll()`, `set()`, `overwrite()`, `hasProperty()`) are removed — those belong in `@_linked/memstore` where Shape subclasses will extend the core Shape and add back NamedNode-backed instance behavior.
|
|
121
|
-
|
|
122
|
-
The decorated property accessors are kept as decorators only — the decorators register PropertyShape metadata, but the accessor implementations (which currently read from the RDF graph) are removed.
|
|
123
|
-
|
|
124
|
-
### Property accessors: `declare` preferred, empty getter if needed
|
|
125
|
-
|
|
126
|
-
Shape properties use `declare` syntax:
|
|
127
|
-
|
|
128
|
-
```typescript
|
|
129
|
-
@linkedShape
|
|
130
|
-
class Person extends Shape {
|
|
131
|
-
@literalProperty({path: name, maxCount: 1})
|
|
132
|
-
declare name: string;
|
|
133
|
-
}
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
This works because query tracing uses Proxy-based interception (see below), not getter overriding. The `declare` keyword has no runtime effect — it only tells TypeScript the property exists for type-checking. The decorator registers the PropertyShape metadata.
|
|
137
|
-
|
|
138
|
-
If it turns out that some mechanism needs a getter to exist at runtime, we can fall back to `get name(): string { return null; }`, but `declare` is the preferred approach.
|
|
139
|
-
|
|
140
|
-
### Proxy-based query tracing (no TestNode)
|
|
141
|
-
|
|
142
|
-
The current `TraceShape.ts` / `TestNode extends NamedNode` mechanism is replaced with Proxy-based tracing. This is already implemented in the codex branch's `SelectQuery.ts`:
|
|
143
|
-
|
|
144
|
-
1. `Shape.select((p) => p.name)` creates a `SelectQueryFactory`.
|
|
145
|
-
2. The factory creates a dummy `new Shape()` instance and wraps it in a `Proxy` via `QueryShape.create()`.
|
|
146
|
-
3. When `p.name` is accessed, the Proxy handler intercepts it, looks up the PropertyShape by label using `getPropertyShapeByLabel()`, and returns a `QueryBuilderObject` (either `QueryValue` for literals or `QueryShape`/`QueryShapeSet` for objects).
|
|
147
|
-
4. The returned `QueryBuilderObject` captures the property path as a linked list of `PropertyShape` references.
|
|
148
|
-
5. After the callback returns, `getQueryPaths()` unwinds these linked lists into `QueryPropertyPath[]`.
|
|
149
|
-
|
|
150
|
-
No `TestNode`, no `NamedNode`, no `Quad` creation. The entire trace is just PropertyShape metadata references.
|
|
151
|
-
|
|
152
|
-
`TraceShape.ts` can be deleted entirely.
|
|
153
|
-
|
|
154
|
-
### SHACL metadata as QResult<NodeShape> (plain JS objects)
|
|
155
|
-
|
|
156
|
-
The current `SHACL.ts` creates actual RDF triples for metadata. This is replaced with plain JS objects typed as `QResult<NodeShape>` — meaning objects with an `id` key and properties defined by the NodeShape schema.
|
|
157
|
-
|
|
158
|
-
The codex branch shows the target structure:
|
|
159
|
-
|
|
160
|
-
- **`NodeShape`** — a class with `id: string`, `label?: string`, `targetClass?: NodeReferenceValue`, `propertyShapes: PropertyShape[]`, and a `properties` getter returning `PropertyShapeResult[]`.
|
|
161
|
-
- **`PropertyShape`** — a class with `id: string`, `label: string`, `path: NodeReferenceValue`, `maxCount?`, `minCount?`, `datatype?: NodeReferenceValue`, `nodeKind?: NodeReferenceValue`, `shape?: NodeReferenceValue`, `name?`, `description?`, `valueShapeClass?: typeof Shape`.
|
|
162
|
-
- **`PropertyShape.getResult()`** returns a `PropertyShapeResult = QResult<null, {path: NodeReferenceValue, ...}>` — the plain JS representation.
|
|
163
|
-
|
|
164
|
-
The key utility to preserve: **given a node shape ID, find the shape class that generated it** — implemented via `ShapeClass.ts` with `registerShapeClass()` / `getShapeClassById()` maps.
|
|
165
|
-
|
|
166
|
-
Validation logic (ValidationReport, ValidationResult, etc.) is removed from core — it operates on RDF triples and belongs in `@_linked/memstore`.
|
|
167
|
-
|
|
168
|
-
### Package.ts switches to plain JS metadata
|
|
169
|
-
|
|
170
|
-
The current `Package.ts` creates RDF quads for registration. In `@_linked/core`, it stores metadata as plain JS maps and `NodeReferenceValue` objects. The codex branch shows the target:
|
|
171
|
-
|
|
172
|
-
- `@linkedShape` calls `ensureShape()` which creates a `NodeShape` with a generated ID (`getNodeShapeUri(packageName, shapeName)`) and registers it via `registerShapeClass()`.
|
|
173
|
-
- `@literalProperty` / `@objectProperty` create `PropertyShape` instances with generated IDs and add them to the `NodeShape`.
|
|
174
|
-
- `targetClass` is set manually after class definition: `Person.shape.targetClass = {id: personClass}`.
|
|
175
|
-
- The React decorators (`@linkedComponent`, `@linkedSetComponent`) are removed.
|
|
176
|
-
|
|
177
|
-
### Ontology files use a namespace function to create NodeReferenceValue objects
|
|
178
|
-
|
|
179
|
-
The current `ontologies/rdf.ts`, `ontologies/shacl.ts`, `ontologies/xsd.ts` etc. use a namespace pattern: a base URI string, then `NamedNode.getOrCreate(base + term)` for each term. In `@_linked/core`, the namespace pattern is preserved but produces `NodeReferenceValue` objects instead of `NamedNode` instances:
|
|
180
|
-
|
|
181
|
-
```typescript
|
|
182
|
-
// ontologies/xsd.ts
|
|
183
|
-
const base = 'http://www.w3.org/2001/XMLSchema#';
|
|
184
|
-
const ns = (term: string): NodeReferenceValue => ({id: base + term});
|
|
185
|
-
|
|
186
|
-
export const xsd = {
|
|
187
|
-
string: ns('string'),
|
|
188
|
-
boolean: ns('boolean'),
|
|
189
|
-
integer: ns('integer'),
|
|
190
|
-
dateTime: ns('dateTime'),
|
|
191
|
-
// ...
|
|
192
|
-
};
|
|
193
|
-
```
|
|
194
|
-
|
|
195
|
-
This keeps the ontology files clean and consistent with the existing code style.
|
|
196
|
-
|
|
197
|
-
---
|
|
198
|
-
|
|
199
|
-
## Phase 1 — Setup and green baseline
|
|
200
|
-
|
|
201
|
-
Create the `rebrand/core/` working folder from scratch with an exact copy of root `src/`, set up build configs that reuse the root `node_modules`, and restructure the tests into two files (query object assertions + type inference assertions) backed by shared query factories. The goal is a fully green baseline before any pruning begins.
|
|
202
|
-
|
|
203
|
-
**Sub-step 1.1 — Create `rebrand/core/` with copy of root `src/`.** ✅ Done (c92af85)
|
|
204
|
-
Create the `rebrand/core/` folder. Copy the entire root `src/` directory into `rebrand/core/src/`. Add build configs (tsconfig, tsconfig-cjs, tsconfig-esm) that reuse the root `node_modules` — follow the same approach used by `rebrand/linked-js` and `rebrand/linked-js2`. Add a `package.json` with scripts for build and test. Add a `jest.config` that works with the folder structure. Verify the package compiles.
|
|
205
|
-
|
|
206
|
-
**Sub-step 1.2 — Move old tests aside, keep one query test working.** ✅ Done (c92af85)
|
|
207
|
-
Move all existing tests into `src/tests/old/`. Create a new `src/tests/query.test.ts` with a single test. Set up the `QueryCaptureStore` pattern (a test spy implementing `IQueryParser` that stores the last query object, assigned to `Shape.queryParser`). Get this one test passing — it should invoke a query like `Person.select(p => p.name)`, capture the query object, and assert the structure of that plain JS query object (type, shape, select paths, property shapes). Reference: the linked-js2 `query.test.tsx` for how this was done.
|
|
208
|
-
|
|
209
|
-
**Sub-step 1.3 — Create query factories (`test-helpers/query-fixtures.ts`).** ✅ Done (500ee53)
|
|
210
|
-
Extract the test shape definitions (Person, Pet, Dog) and property path constants into a shared `src/test-helpers/query-fixtures.ts`. This file exports the shape classes and a structured set of query factory functions — each factory invokes a specific query (e.g. `selectName()`, `selectNestedFriend()`, `filterByName()`, etc.) and returns the promise. The factories don't capture or assert anything themselves — they just invoke the query and return the promise. Each test file decides how to consume the result: `query.test.ts` intercepts the query object via `QueryCaptureStore`, while `@_linked/memstore` will later await real results. This keeps the factories pure and reusable across packages.
|
|
211
|
-
|
|
212
|
-
**Sub-step 1.4 — Build out `query.test.ts` with all ~70 non-React tests.** ✅ Done (5ae6c71)
|
|
213
|
-
Re-enable tests one at a time (or in small batches). For each test: use the corresponding query factory, capture the query object via `QueryCaptureStore`, and assert the structure of the resulting plain JS object in detail (type, select paths, where clauses, sort, limit, CRUD fields, etc.). Cover all 7 describe groups from the original tests: basic property selection, nested/path selection, filtering (where clauses), aggregation/sub-select, type casting/transformations, sorting/limiting, and CRUD operations. All ~70 tests should pass.
|
|
214
|
-
|
|
215
|
-
**Sub-step 1.5 — Create `query.types.test.ts` with compile-only type assertions.** ✅ Done
|
|
216
|
-
Create `src/tests/query.types.test.ts`. For every test in `query.test.ts`, add a corresponding test in this file. Each test is wrapped in `describe.skip` so it never runs at runtime — it only needs to compile. Each test invokes the same query factory and asserts the inferred result types by accessing properties on the result. If the code compiles, TypeScript has verified the types are correct. Use an `expectType<T>()` utility or direct typed variable assignments to make the assertions explicit and thorough. Cover all ~70 select-query tests. For operations that return `Promise<void>` or `DeleteResponse` (not rich inferred types), include at least one type assertion test per operation type — these don't need the same multiplicity as select queries since there's less type inference to verify.
|
|
217
|
-
|
|
218
|
-
**Sub-step 1.6 — Verify full green baseline.** ✅ Done
|
|
219
|
-
Run the full build and test suite. All ~70 tests in `query.test.ts` pass. `query.types.test.ts` compiles without errors. This is the green baseline. Commit.
|
|
220
|
-
|
|
221
|
-
## Phase 2 — Remove React layer ✅ Done
|
|
222
|
-
|
|
223
|
-
- Delete React utility files: `LinkedComponent.ts`, `LinkedComponentClass.tsx`, `Hooks.ts`.
|
|
224
|
-
- Remove `@linkedComponent`, `@linkedSetComponent`, `@linkedComponentClass` from `Package.ts`.
|
|
225
|
-
- Remove React from `package.json` dependencies.
|
|
226
|
-
- Delete all React-related tests (in `src/tests/old/`).
|
|
227
|
-
- Strip React imports from any remaining files.
|
|
228
|
-
- Verify build compiles, tests pass, type inference intact.
|
|
229
|
-
|
|
230
|
-
**Phase 2 follow-up — Keep `preloadFor` in core via generic component-like interface.** ✅ Done
|
|
231
|
-
Reintroduce `preloadFor` without React dependencies by using a generic component-like query interface, and add a minimal preload test + type assertion that mimic component usage.
|
|
232
|
-
|
|
233
|
-
**Expected difficulty:** Low. React is not imported by any of the query or shape files. The active tests don't use React. This is mostly deleting files and cleaning `Package.ts`.
|
|
234
|
-
|
|
235
|
-
## Phase 3 — Replace NamedNode with NodeReferenceValue
|
|
236
|
-
|
|
237
|
-
This is the core transformation. Replace `NamedNode` usage across the codebase with `NodeReferenceValue = {id: string}`. This phase is broken into small sub-steps. After **each** sub-step: verify build compiles, tests pass, and type inference is intact.
|
|
238
|
-
|
|
239
|
-
**Sub-step 3.1 — Introduce NodeReferenceValue as the canonical type.** ✅ Done
|
|
240
|
-
Export `NodeReferenceValue` from a central location (it already exists in `QueryFactory.ts`). Add `toNodeReference()` helper. These coexist with `NamedNode` temporarily.
|
|
241
|
-
|
|
242
|
-
**Sub-step 3.2 — Convert property paths in decorators/PropertyShape.** ✅ Done
|
|
243
|
-
Change `PropertyShape.path` from `NamedNode` to `NodeReferenceValue`. Update `PropertyShapeConfig` to accept `string | NodeReferenceValue`. Update `SHACL.ts` property shape creation to use `toNodeReference()`. Update tests: replace `NamedNode.getOrCreate('name')` with string or `NodeReferenceValue` literals.
|
|
244
|
-
|
|
245
|
-
**Sub-step 3.3 — Convert ontology files.** ✅ Done
|
|
246
|
-
Replace `NamedNode` instantiation in `ontologies/*.ts` with a namespace helper function that creates `NodeReferenceValue` objects. Preserve the existing namespace pattern (`const base = '...'; const ns = (term) => ({id: base + term})`). Update all imports of ontology terms.
|
|
247
|
-
|
|
248
|
-
**Phase 3 follow-up — Require NodeReferenceValue paths in decorators.** ✅ Done
|
|
249
|
-
Restrict `PropertyShapeConfig.path` to `NodeReferenceValue` (no string inputs) since ontology terms already provide NodeReferenceValue. Update fixtures/tests to use NodeReferenceValue paths and assert accordingly.
|
|
250
|
-
|
|
251
|
-
**Sub-step 3.4 — Strip Shape.ts and replace TraceShape/TestNode with Proxy-based tracing.** ✅ Done
|
|
252
|
-
These two changes are tightly coupled and should happen together. Remove the `NamedNode` instance reference from Shape. Remove instance methods that operate on RDF data (`getOne`, `getAll`, `set`, `overwrite`, `hasProperty`, etc.). Keep the static structure: `static shape`, `static queryParser`, static CRUD methods. Keep decorated property accessors as `declare` (or empty getters if needed). Simultaneously, delete `TraceShape.ts` and implement Proxy-based query tracing in `SelectQuery.ts` — the key change: `SelectQueryFactory.getQueryShape()` creates a dummy Shape instance, wraps it in `QueryShape.create()` (Proxy), and invokes the callback. Update `QueryContext.ts` if needed. The codex branch `Shape.ts` and `SelectQuery.ts` are the reference targets.
|
|
253
|
-
|
|
254
|
-
**Phase 3 follow-up — Strengthen query context tests.** ✅ Done
|
|
255
|
-
Expand the two query-context tests to assert the full ShapeReferenceValue structure in the generated query object (both direct context equality and context-based property paths).
|
|
256
|
-
|
|
257
|
-
**Sub-step 3.5 — Convert SHACL.ts to plain JS metadata.** ✅ Done
|
|
258
|
-
Replace the RDF-triple-based `NodeShape` / `PropertyShape` with plain JS classes (reference: codex branch `ShapeDefinition.ts` + `PropertyShape.ts`). Remove `ValidationReport`, `ValidationResult`, and validation logic. Preserve: metadata tracking, `getPropertyShapes()`, `getNodeShapeUri()`, property shape IDs.
|
|
259
|
-
|
|
260
|
-
**Sub-step 3.6 — Convert Package.ts to plain JS metadata.** ✅ Done
|
|
261
|
-
Remove RDF quad creation. Replace with `NodeShape`/`PropertyShape` construction and `registerShapeClass()` calls. Reference: codex branch `decorators.ts`.
|
|
262
|
-
|
|
263
|
-
**Phase 3 follow-up — Store package metadata in plain JS.** ✅ Done
|
|
264
|
-
Keep a `PackageMetadata` registry in the global LINCD tree with the same id as the old package URI, so package info remains accessible without RDF.
|
|
265
|
-
|
|
266
|
-
**Phase 3 follow-up — Add metadata registration tests.** ✅ Done
|
|
267
|
-
Add tests that assert package, node shape, and property shape metadata IDs and structure.
|
|
268
|
-
|
|
269
|
-
**Phase 3 follow-up — Add store routing tests.** ✅ Done
|
|
270
|
-
Add tests that assert LinkedStorage routes queries to the correct store based on the root shape.
|
|
271
|
-
|
|
272
|
-
**Sub-step 3.7 — Convert remaining utilities.** ✅ Done
|
|
273
|
-
Update `ShapeClass.ts`, `LinkedStorage.ts`, and any other files that still import from `models.ts`. Reference: codex branch versions.
|
|
274
|
-
|
|
275
|
-
**Sub-step 3.8 — Delete RDF model files.** ✅ Done (60a95f6)
|
|
276
|
-
Once no file imports from `models.ts`, delete: `models.ts`, `Datafactory.ts`, `LocalQueryResolver.ts`, and RDF-dependent collections (`NodeSet`, `NodeMap`, `NodeURIMappings`, `NodeValuesSet`, `QuadSet`, `QuadMap`, `QuadArray`). Delete CSS files.
|
|
277
|
-
|
|
278
|
-
## Phase 4 — Clean up remaining utilities & exports ✅ Done (a789604)
|
|
279
|
-
|
|
280
|
-
- Audit `utils/` — remove any utilities unused after Phase 2–3 pruning (likely: `NQuads`, `ForwardReasoning`, `Find`, `Order`, `ClassNames`, `Debug`, `LinkedFileStorage`, `Prefix`, `NameSpace`, `Module`, `TraceShape`, `cached`).
|
|
281
|
-
- Audit `collections/` — keep only what core needs (`CoreSet`, `CoreMap`, `ShapeSet`, `ShapeValuesSet`, `SearchMap` — evaluate each).
|
|
282
|
-
- Audit `events/` — keep if the query/shape system uses `EventEmitter`/`EventBatcher`, remove otherwise.
|
|
283
|
-
- Audit `interfaces/` — remove interfaces that are no longer needed (e.g. `IFileStore`, `IClass`, `ISingleGraphObject`, `Component`).
|
|
284
|
-
- Update `index.ts` to export only the `@_linked/core` public API.
|
|
285
|
-
- Rename the package in `package.json` to `@_linked/core`.
|
|
286
|
-
- Verify build compiles, tests pass, type inference intact.
|
|
287
|
-
|
|
288
|
-
## Phase 5 — Final test suite for `@_linked/core` ✅ Done (4a40632)
|
|
289
|
-
|
|
290
|
-
- Remove old/archived tests from `src/tests/old/`.
|
|
291
|
-
- Ensure all tests run and pass against the pruned package.
|
|
292
|
-
- Verify type inference tests still validate that inferred result types are correct.
|
|
293
|
-
|
|
294
|
-
**Phase 5 follow-up — Add unit tests for core utilities.** ✅ Done (69f5ff8)
|
|
295
|
-
Add coverage for `ShapeClass`, extra `LinkedStorage` behaviors, `QueryParser` delegation, `QueryContext` edge cases, and `Package.ts` registration helpers.
|
|
296
|
-
|
|
297
|
-
**Phase 5 follow-up — Add WherePath type guard for safer access.** ✅ Done (commit TBD)
|
|
298
|
-
Add a type guard for `WherePath` so callers can read `args` without `any` casts.
|
|
299
|
-
|
|
300
|
-
## Phase 6 — Integration verification with `@_linked/memstore`
|
|
301
|
-
|
|
302
|
-
- Confirm `@_linked/memstore` can depend on `@_linked/core` as a peer dependency.
|
|
303
|
-
- Import query factories from `@_linked/core` test helpers inside `@_linked/memstore` tests to validate runtime query execution with actual results.
|
|
304
|
-
- Validate that type inference flows correctly from core shapes through memstore query resolution.
|
|
305
|
-
- Tests must fail if inference breaks (no `unknown` or `any` leaks).
|
package/jest.config.js
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */
|
|
2
|
-
module.exports = {
|
|
3
|
-
preset: 'ts-jest',
|
|
4
|
-
testEnvironment: 'node',
|
|
5
|
-
rootDir: 'src/tests',
|
|
6
|
-
testMatch: [
|
|
7
|
-
'**/query.test.ts',
|
|
8
|
-
'**/query.types.test.ts',
|
|
9
|
-
'**/metadata.test.ts',
|
|
10
|
-
'**/store-routing.test.ts',
|
|
11
|
-
'**/core-utils.test.ts',
|
|
12
|
-
],
|
|
13
|
-
testPathIgnorePatterns: ['/old/'],
|
|
14
|
-
transform: {
|
|
15
|
-
'^.+\\.(ts|tsx)$': [
|
|
16
|
-
'ts-jest',
|
|
17
|
-
{
|
|
18
|
-
tsconfig: '<rootDir>/../../tsconfig.json',
|
|
19
|
-
},
|
|
20
|
-
],
|
|
21
|
-
},
|
|
22
|
-
moduleNameMapper: {
|
|
23
|
-
'^(\\.{1,2}/.*)\\.js$': '$1',
|
|
24
|
-
},
|
|
25
|
-
};
|
package/scripts/dual-package.js
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
const fs = require('fs');
|
|
2
|
-
const path = require('path');
|
|
3
|
-
|
|
4
|
-
const root = path.resolve(__dirname,'..');
|
|
5
|
-
const libDir = path.join(root,'lib');
|
|
6
|
-
const cjsDir = path.join(libDir,'cjs');
|
|
7
|
-
const esmDir = path.join(libDir,'esm');
|
|
8
|
-
|
|
9
|
-
const ensureDir = (dir) => {
|
|
10
|
-
if (!fs.existsSync(dir)) {
|
|
11
|
-
fs.mkdirSync(dir,{recursive: true});
|
|
12
|
-
}
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
const writePackageJson = (dir,type) => {
|
|
16
|
-
ensureDir(dir);
|
|
17
|
-
const pkgPath = path.join(dir,'package.json');
|
|
18
|
-
const data = {
|
|
19
|
-
type,
|
|
20
|
-
};
|
|
21
|
-
fs.writeFileSync(pkgPath,JSON.stringify(data,null,2));
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
writePackageJson(cjsDir,'commonjs');
|
|
25
|
-
writePackageJson(esmDir,'module');
|