@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 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
+ }