@pieceful/ravel-projection 0.2.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 +21 -0
- package/README.md +156 -0
- package/package.json +40 -0
- package/src/builder.js +533 -0
- package/src/context.js +108 -0
- package/src/index.d.ts +331 -0
- package/src/index.js +68 -0
- package/src/internal.js +163 -0
- package/src/line-index.js +130 -0
- package/src/mapping.js +369 -0
- package/src/service.js +384 -0
- package/src/transforms.d.ts +29 -0
- package/src/transforms.js +563 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 James Taylor
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
# `@pieceful/ravel-projection`
|
|
2
|
+
|
|
3
|
+
Browser-safe virtual documents, bidirectional source mappings, expansion
|
|
4
|
+
occurrences, generated-code context, incremental deltas, and composable
|
|
5
|
+
transform maps for [Ravel](https://github.com/jostylr/ravel) programs.
|
|
6
|
+
|
|
7
|
+
The package consumes the public `RavelProgram`/`Deliverable` provenance shape
|
|
8
|
+
from `@pieceful/ravel-core`. It has no Node, filesystem, process, editor, or
|
|
9
|
+
language-server dependency, so the same projection can run in an editor host
|
|
10
|
+
or browser worker.
|
|
11
|
+
|
|
12
|
+
## Projection service
|
|
13
|
+
|
|
14
|
+
One service owns the current projection snapshot. Supply every target/artifact
|
|
15
|
+
variant in `projections`; IDs and `pieceful-virtual:` URIs remain stable while
|
|
16
|
+
their monotonically increasing document versions change.
|
|
17
|
+
|
|
18
|
+
```js
|
|
19
|
+
import { createProjectionService } from "@pieceful/ravel-projection";
|
|
20
|
+
|
|
21
|
+
const projections = createProjectionService({
|
|
22
|
+
workspaceId: "demo",
|
|
23
|
+
projections: [
|
|
24
|
+
{
|
|
25
|
+
targetId: "web",
|
|
26
|
+
artifactId: "dist/app.ts",
|
|
27
|
+
languageId: "typescript",
|
|
28
|
+
stage: "assembled",
|
|
29
|
+
},
|
|
30
|
+
],
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
const delta = await projections.update({
|
|
34
|
+
id: "snapshot-1",
|
|
35
|
+
program,
|
|
36
|
+
sourceVersions: { "guide.md": 7 },
|
|
37
|
+
sourceTexts: { "guide.md": guideText },
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
const [virtual] = delta.opened;
|
|
41
|
+
const generated = projections.toVirtual(
|
|
42
|
+
{ uri: "guide.md", offset: 120 },
|
|
43
|
+
{
|
|
44
|
+
targetId: "web",
|
|
45
|
+
artifactId: "dist/app.ts",
|
|
46
|
+
stage: "assembled",
|
|
47
|
+
projectionVersion: virtual.version,
|
|
48
|
+
},
|
|
49
|
+
);
|
|
50
|
+
const authored = projections.toSource(
|
|
51
|
+
virtual.id,
|
|
52
|
+
{ start: 12, end: 18 },
|
|
53
|
+
{
|
|
54
|
+
projectionVersion: virtual.version,
|
|
55
|
+
},
|
|
56
|
+
);
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
`update()` returns opened, changed, unchanged, and closed documents plus
|
|
60
|
+
minimal-or-full text changes. `scheduleUpdate()` supports interactive and
|
|
61
|
+
background work; a superseding update or `AbortSignal` prevents a stale build
|
|
62
|
+
from becoming current. Treat returned virtual documents and deltas as
|
|
63
|
+
immutable.
|
|
64
|
+
|
|
65
|
+
Mapping queries return every match because one authored piece can occur in
|
|
66
|
+
many artifacts or expansion sites. Narrow them with `targetId`, `artifactId`,
|
|
67
|
+
`stage`, and `occurrenceId`; use `affinity` at zero-width boundaries. Invalid
|
|
68
|
+
or explicitly stale low-level queries return `{ ok: false, reason, matches: [] }`
|
|
69
|
+
rather than throwing. Service convenience methods return an empty match array
|
|
70
|
+
for an invalid selection, so callers that need a reason should use the
|
|
71
|
+
low-level `mapSource*`/`mapVirtual*` functions.
|
|
72
|
+
|
|
73
|
+
## Provenance kinds
|
|
74
|
+
|
|
75
|
+
Each `ProjectionSegment` describes a generated UTF-16 offset range and its
|
|
76
|
+
best available authored provenance.
|
|
77
|
+
|
|
78
|
+
| Kind | Meaning | Reverse-edit status |
|
|
79
|
+
| ------------- | -------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- |
|
|
80
|
+
| `exact` | Generated code is character-for-character authored text. Exact subranges are reversible when source and generated lengths agree. | Eligible for policy-controlled edits. |
|
|
81
|
+
| `anchored` | Generated text has a responsible invocation, definition, or transform location, but no character correspondence. | Navigation only. |
|
|
82
|
+
| `transformed` | A declared offset or source-map transform preserves a character correspondence for this span. | Mappable, but not automatically editable by the current edit policy. |
|
|
83
|
+
| `opaque` | A transform supplied no usable mapping; only a responsible anchor may remain. | Navigation only. |
|
|
84
|
+
| `synthetic` | The tool inserted text with no authored destination. | Not editable without a separate host policy, such as an imports destination. |
|
|
85
|
+
|
|
86
|
+
`writable: true` on a mapping match is necessary, not sufficient, for an
|
|
87
|
+
automatic source edit. A host must still enforce the stricter policy in
|
|
88
|
+
`@pieceful/ravel-language-service`.
|
|
89
|
+
|
|
90
|
+
Expansion occurrences form a parent/child tree and preserve invocation and
|
|
91
|
+
definition locations. `generatedContext()` returns the occurrence breadcrumb,
|
|
92
|
+
sibling expansions, a bounded visible range, and categorized highlights for a
|
|
93
|
+
generated-code overlay. It does not infer a unique occurrence when the source
|
|
94
|
+
appears more than once.
|
|
95
|
+
|
|
96
|
+
## Projection stages
|
|
97
|
+
|
|
98
|
+
Stages are semantic labels, not an implied build pipeline:
|
|
99
|
+
|
|
100
|
+
- `authoring`: a language-shaped view closest to the authored chunk.
|
|
101
|
+
- `assembled`: expanded chunks arranged as an artifact; the normal native
|
|
102
|
+
language-service input.
|
|
103
|
+
- `transformed`: output after a declared analysis transform.
|
|
104
|
+
- `emitted`: final generated output. Its default capabilities disable
|
|
105
|
+
completion and writable edits while retaining navigation and diagnostics.
|
|
106
|
+
|
|
107
|
+
The other stages default to navigation, diagnostics, completion, and writable
|
|
108
|
+
mapping support. `stageCapabilities()` or build options can reduce these
|
|
109
|
+
capabilities. Do not advertise a later stage if the transform needed to create
|
|
110
|
+
it executes effects: `validateAnalysisTransform()` accepts only transforms
|
|
111
|
+
declared pure, without effects or authorities, and with a valid mapping
|
|
112
|
+
capability.
|
|
113
|
+
|
|
114
|
+
## Transform authors
|
|
115
|
+
|
|
116
|
+
Transform helpers are exported from `@pieceful/ravel-projection/transforms`.
|
|
117
|
+
|
|
118
|
+
```js
|
|
119
|
+
import {
|
|
120
|
+
applyTransformMap,
|
|
121
|
+
createIndentOffsetMap,
|
|
122
|
+
} from "@pieceful/ravel-projection/transforms";
|
|
123
|
+
|
|
124
|
+
const indented = createIndentOffsetMap(assembled.text, 2);
|
|
125
|
+
if (!indented.ok) throw new Error(indented.reason);
|
|
126
|
+
|
|
127
|
+
const transformed = applyTransformMap(assembled, indented.text, indented.map, {
|
|
128
|
+
name: "indent",
|
|
129
|
+
stage: "transformed",
|
|
130
|
+
});
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Use the narrowest honest mapping capability:
|
|
134
|
+
|
|
135
|
+
- `identityTransformMap()` preserves the input mapping kind.
|
|
136
|
+
- Offset maps use ordered `copy`, `mapped`, `inserted`, and `removed` spans.
|
|
137
|
+
Indent, dedent, EOL normalization, offset lookup, and composition helpers are
|
|
138
|
+
included. A non-identity copied/mapped span becomes `transformed`; inserted
|
|
139
|
+
output becomes `anchored` when `transformSource` is supplied and `synthetic`
|
|
140
|
+
otherwise; removed input has no output range.
|
|
141
|
+
- `normalizeSourceMap()` decodes a version-3 source map. `applyTransformMap()`
|
|
142
|
+
converts matching points into UTF-16 offset spans for one input virtual
|
|
143
|
+
document. Gaps, foreign sources, and source-map regions without usable
|
|
144
|
+
points remain unmapped; this is not a proof that arbitrary source-map edits
|
|
145
|
+
are reversible.
|
|
146
|
+
- `opaqueTransformMap()` deliberately degrades the entire output to opaque
|
|
147
|
+
provenance, optionally retaining an anchor. Use it whenever a transform
|
|
148
|
+
cannot supply a truthful map.
|
|
149
|
+
|
|
150
|
+
`applyTransformMap()` rejects invalid maps and maps whose declared input or
|
|
151
|
+
output lengths do not match the supplied texts. Offset-map composition only
|
|
152
|
+
works when adjacent map lengths agree. All public offsets are UTF-16 code-unit
|
|
153
|
+
offsets; `createLineIndex()`, `positionAt()`, and `offsetAt()` provide explicit
|
|
154
|
+
UTF-8, UTF-16, or UTF-32 line/character conversion for protocol boundaries.
|
|
155
|
+
|
|
156
|
+
MIT © James Taylor
|
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@pieceful/ravel-projection",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"sideEffects": false,
|
|
6
|
+
"description": "Browser-safe virtual documents, source projections, and generated-code context for Ravel.",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"author": "James Taylor",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/jostylr/ravel.git",
|
|
12
|
+
"directory": "packages/projection"
|
|
13
|
+
},
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://github.com/jostylr/ravel/issues"
|
|
16
|
+
},
|
|
17
|
+
"homepage": "https://ravel.jostylr.com/",
|
|
18
|
+
"engines": {
|
|
19
|
+
"node": ">=22"
|
|
20
|
+
},
|
|
21
|
+
"keywords": [
|
|
22
|
+
"ravel",
|
|
23
|
+
"literate-programming",
|
|
24
|
+
"virtual-document",
|
|
25
|
+
"source-map"
|
|
26
|
+
],
|
|
27
|
+
"publishConfig": {
|
|
28
|
+
"access": "public"
|
|
29
|
+
},
|
|
30
|
+
"exports": {
|
|
31
|
+
".": "./src/index.js",
|
|
32
|
+
"./transforms": "./src/transforms.js"
|
|
33
|
+
},
|
|
34
|
+
"types": "./src/index.d.ts",
|
|
35
|
+
"files": [
|
|
36
|
+
"src",
|
|
37
|
+
"README.md",
|
|
38
|
+
"LICENSE"
|
|
39
|
+
]
|
|
40
|
+
}
|