mapples 0.2.0-beta.1 → 0.2.0-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +70 -22
- package/dist/adopt/scan.d.ts +8 -2
- package/dist/adopt/scan.js +31 -13
- package/dist/adopt/scan.js.map +1 -1
- package/dist/api/client.d.ts +9 -1
- package/dist/api/client.js +21 -2
- package/dist/api/client.js.map +1 -1
- package/dist/api/commit.d.ts +9 -0
- package/dist/api/commit.js +32 -2
- package/dist/api/commit.js.map +1 -1
- package/dist/api/errors.js +8 -0
- package/dist/api/errors.js.map +1 -1
- package/dist/api/objects.d.ts +22 -5
- package/dist/api/objects.js +151 -10
- package/dist/api/objects.js.map +1 -1
- package/dist/api/poll.d.ts +5 -3
- package/dist/api/poll.js +17 -6
- package/dist/api/poll.js.map +1 -1
- package/dist/assets/assets.d.ts +9 -0
- package/dist/assets/assets.js +33 -4
- package/dist/assets/assets.js.map +1 -1
- package/dist/codegen/emit.d.ts +27 -1
- package/dist/codegen/emit.js +130 -9
- package/dist/codegen/emit.js.map +1 -1
- package/dist/codegen/imports.d.ts +2 -0
- package/dist/codegen/imports.js +38 -0
- package/dist/codegen/imports.js.map +1 -1
- package/dist/codegen/instances.d.ts +16 -0
- package/dist/codegen/instances.js +141 -0
- package/dist/codegen/instances.js.map +1 -0
- package/dist/codegen/styles.d.ts +11 -0
- package/dist/codegen/styles.js +131 -0
- package/dist/codegen/styles.js.map +1 -0
- package/dist/commands/impl/createImpl.js +8 -4
- package/dist/commands/impl/createImpl.js.map +1 -1
- package/dist/commands/impl/initImpl.js +5 -4
- package/dist/commands/impl/initImpl.js.map +1 -1
- package/dist/commands/impl/syncImpl.js +20 -2
- package/dist/commands/impl/syncImpl.js.map +1 -1
- package/dist/merge/applyOps.d.ts +1 -1
- package/dist/merge/applyOps.js +33 -2
- package/dist/merge/applyOps.js.map +1 -1
- package/dist/merge/diff.d.ts +1 -1
- package/dist/merge/diff.js +30 -17
- package/dist/merge/diff.js.map +1 -1
- package/dist/merge/threeWay.d.ts +1 -1
- package/dist/merge/threeWay.js +38 -6
- package/dist/merge/threeWay.js.map +1 -1
- package/dist/merge/toEdits.d.ts +1 -1
- package/dist/merge/toEdits.js +4 -1
- package/dist/merge/toEdits.js.map +1 -1
- package/dist/nav/navigatorTree.d.ts +78 -0
- package/dist/nav/navigatorTree.js +410 -0
- package/dist/nav/navigatorTree.js.map +1 -0
- package/dist/nav/placement.d.ts +53 -0
- package/dist/nav/placement.js +260 -0
- package/dist/nav/placement.js.map +1 -0
- package/dist/nav/routeTree.d.ts +8 -2
- package/dist/nav/routeTree.js +79 -151
- package/dist/nav/routeTree.js.map +1 -1
- package/dist/nav/screenOptions.d.ts +15 -0
- package/dist/nav/screenOptions.js +213 -0
- package/dist/nav/screenOptions.js.map +1 -0
- package/dist/project/baseStore.d.ts +8 -0
- package/dist/project/baseStore.js +15 -0
- package/dist/project/baseStore.js.map +1 -1
- package/dist/project/componentsMap.d.ts +7 -0
- package/dist/project/componentsMap.js +21 -0
- package/dist/project/componentsMap.js.map +1 -0
- package/dist/project/config.d.ts +12 -3
- package/dist/project/config.js +11 -2
- package/dist/project/config.js.map +1 -1
- package/dist/project/env.d.ts +10 -3
- package/dist/project/env.js +23 -5
- package/dist/project/env.js.map +1 -1
- package/dist/project/pagesMap.d.ts +2 -0
- package/dist/project/pagesMap.js.map +1 -1
- package/dist/services/adoptService.d.ts +3 -0
- package/dist/services/adoptService.js +346 -38
- package/dist/services/adoptService.js.map +1 -1
- package/dist/services/clientFactory.js +4 -2
- package/dist/services/clientFactory.js.map +1 -1
- package/dist/services/doctorService.js +77 -66
- package/dist/services/doctorService.js.map +1 -1
- package/dist/services/syncEngine.d.ts +7 -0
- package/dist/services/syncEngine.js +428 -292
- package/dist/services/syncEngine.js.map +1 -1
- package/dist/types.d.ts +21 -1
- package/dist/types.js +22 -0
- package/dist/types.js.map +1 -1
- package/package.json +2 -2
- package/templates/app/_layout.tsx +3 -0
- package/templates/mapples/sid.d.ts +6 -0
package/README.md
CHANGED
|
@@ -1,42 +1,90 @@
|
|
|
1
1
|
# mapples
|
|
2
2
|
|
|
3
3
|
Two-way code sync between **Mapples Creator** and your Expo project (RFC-0002, over the JPATCH/1
|
|
4
|
-
protocol from RFC-0001). Screens live as generated, editable TSX in your repo —
|
|
5
|
-
is the code-side truth, extracted back into RenderDom and merged 3-way against
|
|
4
|
+
protocol from RFC-0001). Screens and components live as generated, editable TSX in your repo —
|
|
5
|
+
`$sid`-tagged JSX is the code-side truth, extracted back into RenderDom and merged 3-way against
|
|
6
|
+
the canvas.
|
|
6
7
|
|
|
7
8
|
```bash
|
|
8
|
-
npx mapples create my-app --project
|
|
9
|
-
npx mapples init --project
|
|
10
|
-
npx mapples sync
|
|
11
|
-
npx mapples
|
|
12
|
-
npx mapples
|
|
9
|
+
npx mapples create my-app --secret <project API secret> # scaffold a connected Expo app
|
|
10
|
+
npx mapples init --secret <project API secret> # link an existing Expo app
|
|
11
|
+
npx mapples sync # pull + push in one run
|
|
12
|
+
npx mapples sync --yes # …accepting every adoption proposal
|
|
13
|
+
npx mapples adopt app/settings.tsx # adopt a plain RN screen, no prompt
|
|
14
|
+
npx mapples doctor # $sid lint + drift check
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
The project API secret comes from Creator (Project → Settings). It identifies the project and
|
|
18
|
+
authenticates the CLI; it is stored in `.mapples/secret` (git-ignored) or read from
|
|
19
|
+
`MAPPLES_SECRET`. A read-scoped secret pulls only; pushes need a write-scoped one.
|
|
20
|
+
|
|
21
|
+
## Where code lives
|
|
22
|
+
|
|
23
|
+
| In Creator | In your repo |
|
|
24
|
+
| ------------------------------ | ------------------------------------------------------------------- |
|
|
25
|
+
| A screen inside a navigator | Its expo-router route file: `app/<segment>.tsx` |
|
|
26
|
+
| A screen outside any section | `mapples/pages/<Name>.tsx` — moves into `app/` once it is placed |
|
|
27
|
+
| Navigators (stack/tabs/drawer) | CLI-owned `app/**/_layout.tsx`, regenerated every sync |
|
|
28
|
+
| A saved component | `mapples/components/<Name>.tsx` |
|
|
29
|
+
| A component placed on a screen | `import Card from '../mapples/components/Card'` + `<Card $sid … />` |
|
|
30
|
+
| Theme | `mapples/theme.ts` |
|
|
31
|
+
| Assets | `mapples/assets/` + generated `assetMap.ts` |
|
|
32
|
+
|
|
33
|
+
A routed file opens with a `// mapples-route: <id>` marker: renaming the file renames the route
|
|
34
|
+
in Creator, and a Creator rename moves the file. Apps born from `mapples create` own `app/`
|
|
35
|
+
from the root `_layout.tsx`; apps linked with `mapples init` keep the `app/(mapples)` group.
|
|
36
|
+
|
|
37
|
+
Generated files keep their styles in a dictionary below the component, the way hand-written
|
|
38
|
+
Mapples code does — never inline:
|
|
39
|
+
|
|
40
|
+
```tsx
|
|
41
|
+
export default function Login() {
|
|
42
|
+
return <Text $sid="nd_…" text="Sign In" styled={{ style: styles.signInText }} />;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const styles = Styler.create({
|
|
46
|
+
signInText: { fontSize: 24, fontWeight: 'bold' },
|
|
47
|
+
});
|
|
13
48
|
```
|
|
14
49
|
|
|
15
50
|
## What sync does
|
|
16
51
|
|
|
17
|
-
1.
|
|
18
|
-
|
|
19
|
-
|
|
52
|
+
1. Adopts new files you wrote (`app/*.tsx`, `mapples/pages/*.tsx`, `mapples/components/*.tsx`)
|
|
53
|
+
after a prompt (`--yes` to accept, `--no-adopt` to skip): react-native primitives become the
|
|
54
|
+
matching `@mapples/ui` components with `styled` props, anything else is wrapped as an opaque
|
|
55
|
+
`Custom` node; a component file becomes a Creator component, and a page that uses it links
|
|
56
|
+
to it in the same run.
|
|
57
|
+
2. Extracts every managed file (`$sid` JSX → RenderDom; hooks, handlers and wrappers are
|
|
58
|
+
invisible). An element you added without a `$sid` is tagged the same way adoption would tag
|
|
59
|
+
it — it never stays invisible. A `styled={{ style: styles.card }}` reference is read through
|
|
60
|
+
your `StyleSheet.create` / `Styler.create` / plain-object dictionary.
|
|
61
|
+
3. Pulls the delta since the last synced HEAD (cold bootstrap when too far behind).
|
|
62
|
+
4. 3-way merges per `$sid` node, per prop key: disjoint edits auto-merge; same-prop or
|
|
20
63
|
delete-vs-edit conflicts **deprecate** the file (`_depr_<ts>_<name>.tsx.old` — your version is
|
|
21
64
|
never overwritten or deleted) and regenerate it from Creator.
|
|
22
|
-
|
|
23
|
-
|
|
65
|
+
5. Writes remote changes into your files **surgically** — user code is preserved byte-for-byte.
|
|
66
|
+
A Creator style edit lands in the dictionary entry the tag references when that element is
|
|
67
|
+
its only reader, and inline (with a warning) when the entry is shared.
|
|
68
|
+
6. Pushes your edits as JPATCH transactions of at most 200 ops; 409s rebase and retry; going
|
|
24
69
|
offline parks ops in `.mapples/outbox/` and drains them next run.
|
|
25
|
-
|
|
70
|
+
7. Rewrites client-minted `c_` ids to server ids from the response `idMap`.
|
|
26
71
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
72
|
+
Every lossy step is reported: expression props keep their last-known canvas value
|
|
73
|
+
(`NON_LITERAL_PROP`), props a component instance cannot carry stay in code only, and so on.
|
|
74
|
+
Nothing is dropped silently.
|
|
30
75
|
|
|
31
76
|
## Project state
|
|
32
77
|
|
|
33
78
|
```
|
|
34
79
|
.mapples/
|
|
35
|
-
config.json
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
80
|
+
config.json # projectId, apiUrl, pagesDir, routesDir, componentsDir, schema — committable
|
|
81
|
+
secret # project API secret — git-ignored (or MAPPLES_SECRET)
|
|
82
|
+
head # last synced HEAD + seq
|
|
83
|
+
pages.json # pageId <-> file mapping (+ route)
|
|
84
|
+
components.json # componentId <-> file mapping
|
|
85
|
+
base/ # canonical JSON per entity at the last synced HEAD
|
|
86
|
+
outbox/ # parked transactions (offline)
|
|
40
87
|
```
|
|
41
88
|
|
|
42
|
-
|
|
89
|
+
`mapples/sid.d.ts` declares the transient JSX attributes (`$sid`, `$refs`, `$data`, `$actions`,
|
|
90
|
+
`$fallback`); `babel-plugin-mapples-sid` strips them from production bundles.
|
package/dist/adopt/scan.d.ts
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import type { PagesMap } from '../project/pagesMap.js';
|
|
2
1
|
import type { AdoptCandidate } from '../types.js';
|
|
3
|
-
export
|
|
2
|
+
export interface ScanDirs {
|
|
3
|
+
routesDir: string;
|
|
4
|
+
pagesDir: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function isUnder(file: string, dir: string): boolean;
|
|
7
|
+
/** Files pages.json and components.json already own. */
|
|
8
|
+
export declare function managedFiles(root: string): Set<string>;
|
|
9
|
+
export declare function scanForCandidates(root: string, managed: Set<string>, dirs: ScanDirs): AdoptCandidate[];
|
|
4
10
|
export declare function toRelative(root: string, file: string): string;
|
package/dist/adopt/scan.js
CHANGED
|
@@ -1,12 +1,32 @@
|
|
|
1
|
-
// Adoption scan: exported React components under
|
|
2
|
-
// and
|
|
1
|
+
// Adoption scan: exported React components under the route tree, the pages
|
|
2
|
+
// directory and app/ + mapples/ with no $sid and absent from the pages and
|
|
3
|
+
// components manifests. Unadopted files are never touched.
|
|
4
|
+
//
|
|
5
|
+
// Classification follows the file layout (RFC-0002 §5): a file under
|
|
6
|
+
// routesDir is a ROUTED page (it joins the navigation at its position), one
|
|
7
|
+
// under pagesDir — or elsewhere in app/ outside the managed tree — is a page
|
|
8
|
+
// outside the navigation, anything else is a component.
|
|
3
9
|
import { existsSync, readFileSync, readdirSync } from 'node:fs';
|
|
4
|
-
import { join, relative, sep } from 'node:path';
|
|
10
|
+
import { isAbsolute, join, relative, sep } from 'node:path';
|
|
5
11
|
import { scanComponents } from '@mapples/sid-ast';
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
12
|
+
import { readComponentsMap } from '../project/componentsMap.js';
|
|
13
|
+
import { readPagesMap } from '../project/pagesMap.js';
|
|
14
|
+
export function isUnder(file, dir) {
|
|
15
|
+
const rel = relative(dir, file);
|
|
16
|
+
return rel !== '' && !rel.startsWith('..') && !isAbsolute(rel);
|
|
17
|
+
}
|
|
18
|
+
/** Files pages.json and components.json already own. */
|
|
19
|
+
export function managedFiles(root) {
|
|
20
|
+
return new Set([
|
|
21
|
+
...Object.values(readPagesMap(root)).map((m) => m.file),
|
|
22
|
+
...Object.values(readComponentsMap(root)).map((m) => m.file),
|
|
23
|
+
]);
|
|
24
|
+
}
|
|
25
|
+
export function scanForCandidates(root, managed, dirs) {
|
|
9
26
|
const candidates = [];
|
|
27
|
+
const scanRoots = [
|
|
28
|
+
...new Set(['app', 'mapples', dirs.routesDir.split(sep)[0], dirs.pagesDir.split(sep)[0]]),
|
|
29
|
+
];
|
|
10
30
|
const walk = (dir) => {
|
|
11
31
|
const abs = join(root, dir);
|
|
12
32
|
if (!existsSync(abs))
|
|
@@ -30,18 +50,16 @@ export function scanForCandidates(root, pagesMap) {
|
|
|
30
50
|
if (info.hasSid || !info.hasJsx)
|
|
31
51
|
continue;
|
|
32
52
|
if (info.markers.length > 0)
|
|
33
|
-
continue; //
|
|
53
|
+
continue; // generated files / files already carrying a route
|
|
34
54
|
const componentName = info.exportedComponents[0];
|
|
35
55
|
if (!componentName)
|
|
36
56
|
continue;
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
kind: rel.split(sep)[0] === 'app' ? 'page' : 'component',
|
|
41
|
-
});
|
|
57
|
+
const routed = isUnder(rel, dirs.routesDir);
|
|
58
|
+
const page = routed || isUnder(rel, dirs.pagesDir) || rel.split(sep)[0] === 'app';
|
|
59
|
+
candidates.push({ file: rel, componentName, kind: page ? 'page' : 'component', routed });
|
|
42
60
|
}
|
|
43
61
|
};
|
|
44
|
-
for (const dir of
|
|
62
|
+
for (const dir of scanRoots)
|
|
45
63
|
walk(dir);
|
|
46
64
|
return candidates.sort((a, b) => (a.file < b.file ? -1 : 1));
|
|
47
65
|
}
|
package/dist/adopt/scan.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scan.js","sourceRoot":"","sources":["../../src/adopt/scan.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"scan.js","sourceRoot":"","sources":["../../src/adopt/scan.ts"],"names":[],"mappings":"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"}
|
package/dist/api/client.d.ts
CHANGED
|
@@ -7,6 +7,8 @@ export interface JpatchClientOptions {
|
|
|
7
7
|
token?: string;
|
|
8
8
|
actor?: string;
|
|
9
9
|
origin?: string;
|
|
10
|
+
/** Host serving asset bodies (per-stage assets host); defaults to baseUrl. */
|
|
11
|
+
assetsBaseUrl?: string;
|
|
10
12
|
}
|
|
11
13
|
/**
|
|
12
14
|
* Thin, faithful JPATCH/1 transport (RFC-0001 §5–§8). No retry logic here —
|
|
@@ -17,14 +19,20 @@ export declare class JpatchClient {
|
|
|
17
19
|
readonly projectId: string;
|
|
18
20
|
readonly actor: string | undefined;
|
|
19
21
|
readonly origin: string | undefined;
|
|
22
|
+
readonly assetsBaseUrl: string;
|
|
20
23
|
constructor(opts: JpatchClientOptions);
|
|
21
24
|
private path;
|
|
22
25
|
commitRaw(envelope: Envelope): Promise<CommitOk>;
|
|
23
|
-
|
|
26
|
+
/** One delta page. The cursor is a SEQUENCE number (`since_seq`), not a head. */
|
|
27
|
+
pullOnce(sinceSeq: number): Promise<Delta>;
|
|
24
28
|
bootstrap(): Promise<Bootstrap>;
|
|
25
29
|
getObject(hash: string): Promise<unknown>;
|
|
26
30
|
/** Binary blob fetch (asset bodies, addressed as `sha256:<hex>`). */
|
|
27
31
|
getObjectBytes(hash: string): Promise<Uint8Array>;
|
|
32
|
+
/** Batched blob fetch: POST objects/get {hashes} -> {objects} (RFC-0001 §6, key-readable). */
|
|
33
|
+
objectsGet(hashes: string[]): Promise<Record<string, unknown>>;
|
|
34
|
+
/** Fetch raw bytes for an asset `link` (served from the assets host). */
|
|
35
|
+
getBytesAtPath(path: string): Promise<Uint8Array>;
|
|
28
36
|
/** Which of these content hashes is the store missing? Returns hash -> signed PUT URL. */
|
|
29
37
|
have(hashes: string[]): Promise<Record<string, string>>;
|
|
30
38
|
history(limit?: number): Promise<{
|
package/dist/api/client.js
CHANGED
|
@@ -9,10 +9,12 @@ export class JpatchClient {
|
|
|
9
9
|
projectId;
|
|
10
10
|
actor;
|
|
11
11
|
origin;
|
|
12
|
+
assetsBaseUrl;
|
|
12
13
|
constructor(opts) {
|
|
13
14
|
this.projectId = opts.projectId;
|
|
14
15
|
this.actor = opts.actor;
|
|
15
16
|
this.origin = opts.origin;
|
|
17
|
+
this.assetsBaseUrl = (opts.assetsBaseUrl ?? opts.baseUrl).replace(/\/+$/, '');
|
|
16
18
|
this.http = axios.create({
|
|
17
19
|
baseURL: opts.baseUrl.replace(/\/+$/, ''),
|
|
18
20
|
headers: opts.token ? { 'X-API-Key': opts.token } : {},
|
|
@@ -31,8 +33,9 @@ export class JpatchClient {
|
|
|
31
33
|
return res.data;
|
|
32
34
|
throw errorFromBody(res.status, res.data);
|
|
33
35
|
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
+
/** One delta page. The cursor is a SEQUENCE number (`since_seq`), not a head. */
|
|
37
|
+
async pullOnce(sinceSeq) {
|
|
38
|
+
const res = await this.http.get(this.path(), { params: { since_seq: sinceSeq } });
|
|
36
39
|
if (res.status === 200)
|
|
37
40
|
return res.data;
|
|
38
41
|
throw errorFromBody(res.status, res.data);
|
|
@@ -58,6 +61,22 @@ export class JpatchClient {
|
|
|
58
61
|
return new Uint8Array(res.data);
|
|
59
62
|
throw errorFromBody(res.status, JSON.parse(Buffer.from(res.data).toString('utf8')));
|
|
60
63
|
}
|
|
64
|
+
/** Batched blob fetch: POST objects/get {hashes} -> {objects} (RFC-0001 §6, key-readable). */
|
|
65
|
+
async objectsGet(hashes) {
|
|
66
|
+
const res = await this.http.post(this.path('/objects/get'), { hashes });
|
|
67
|
+
if (res.status === 200) {
|
|
68
|
+
return (res.data.objects ?? {});
|
|
69
|
+
}
|
|
70
|
+
throw errorFromBody(res.status, res.data);
|
|
71
|
+
}
|
|
72
|
+
/** Fetch raw bytes for an asset `link` (served from the assets host). */
|
|
73
|
+
async getBytesAtPath(path) {
|
|
74
|
+
const url = path.startsWith('http') ? path : `${this.assetsBaseUrl}${path}`;
|
|
75
|
+
const res = await this.http.get(url, { responseType: 'arraybuffer' });
|
|
76
|
+
if (res.status === 200)
|
|
77
|
+
return new Uint8Array(res.data);
|
|
78
|
+
throw errorFromBody(res.status, JSON.parse(Buffer.from(res.data).toString('utf8')));
|
|
79
|
+
}
|
|
61
80
|
/** Which of these content hashes is the store missing? Returns hash -> signed PUT URL. */
|
|
62
81
|
async have(hashes) {
|
|
63
82
|
if (hashes.length > 500)
|
package/dist/api/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,UAAU,EAAsB,MAAM,OAAO,CAAC;AAG9D,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"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"}
|
package/dist/api/commit.d.ts
CHANGED
|
@@ -2,6 +2,15 @@ import type { CommitOk, Envelope, JpatchOp } from '../types.js';
|
|
|
2
2
|
import type { JpatchClient } from './client.js';
|
|
3
3
|
export declare function mintTxId(): string;
|
|
4
4
|
export declare function mintCid(): string;
|
|
5
|
+
/**
|
|
6
|
+
* Rewrite every cid that an earlier transaction already resolved (its `idMap`)
|
|
7
|
+
* to the server id, wherever it appears in `ops` — `id`, `data.parent`,
|
|
8
|
+
* children refs, props that point at sibling nodes. cids are transaction-scoped
|
|
9
|
+
* (RFC-0001 §5.2, invariant 5): once the create that minted one has committed,
|
|
10
|
+
* a later transaction must reference the DB id or the server answers
|
|
11
|
+
* CID_UNRESOLVED. Returns new objects; `ops` is left untouched.
|
|
12
|
+
*/
|
|
13
|
+
export declare function resolveCids(ops: JpatchOp[], idMap: Record<string, string>): JpatchOp[];
|
|
5
14
|
export interface CommitParams {
|
|
6
15
|
base: string;
|
|
7
16
|
ops: JpatchOp[];
|
package/dist/api/commit.js
CHANGED
|
@@ -7,6 +7,33 @@ export function mintTxId() {
|
|
|
7
7
|
export function mintCid() {
|
|
8
8
|
return `c_${ulid()}`;
|
|
9
9
|
}
|
|
10
|
+
/**
|
|
11
|
+
* Rewrite every cid that an earlier transaction already resolved (its `idMap`)
|
|
12
|
+
* to the server id, wherever it appears in `ops` — `id`, `data.parent`,
|
|
13
|
+
* children refs, props that point at sibling nodes. cids are transaction-scoped
|
|
14
|
+
* (RFC-0001 §5.2, invariant 5): once the create that minted one has committed,
|
|
15
|
+
* a later transaction must reference the DB id or the server answers
|
|
16
|
+
* CID_UNRESOLVED. Returns new objects; `ops` is left untouched.
|
|
17
|
+
*/
|
|
18
|
+
export function resolveCids(ops, idMap) {
|
|
19
|
+
if (!Object.keys(idMap).some((k) => k.startsWith('c_')))
|
|
20
|
+
return ops;
|
|
21
|
+
const walk = (value) => {
|
|
22
|
+
if (typeof value === 'string') {
|
|
23
|
+
return value.startsWith('c_') && idMap[value] !== undefined ? idMap[value] : value;
|
|
24
|
+
}
|
|
25
|
+
if (Array.isArray(value))
|
|
26
|
+
return value.map(walk);
|
|
27
|
+
if (value !== null && typeof value === 'object') {
|
|
28
|
+
const out = {};
|
|
29
|
+
for (const [k, v] of Object.entries(value))
|
|
30
|
+
out[k] = walk(v);
|
|
31
|
+
return out;
|
|
32
|
+
}
|
|
33
|
+
return value;
|
|
34
|
+
};
|
|
35
|
+
return ops.map((op) => walk(op));
|
|
36
|
+
}
|
|
10
37
|
export function buildEnvelope(client, params) {
|
|
11
38
|
const envelope = {
|
|
12
39
|
protocol: 'jpatch/1',
|
|
@@ -38,8 +65,11 @@ export async function commitWithTransportRetry(client, envelope, maxAttempts = 5
|
|
|
38
65
|
}
|
|
39
66
|
catch (err) {
|
|
40
67
|
if (err instanceof JpatchError && err.code === 'FORBIDDEN') {
|
|
41
|
-
// RFC-0003: read-scoped keys can pull but not push.
|
|
42
|
-
|
|
68
|
+
// RFC-0003: read-scoped keys can pull but not push. Prefer the
|
|
69
|
+
// server's own guidance when it sends one.
|
|
70
|
+
const detail = err.message.replace(/^FORBIDDEN:\s*/, '');
|
|
71
|
+
throw new Error(`push rejected: ${detail ||
|
|
72
|
+
'this API key is read-scoped — generate a read & write key in Creator (Project → Settings)'} (then re-run \`mapples init --secret <key>\`)`);
|
|
43
73
|
}
|
|
44
74
|
if (!isNetworkError(err))
|
|
45
75
|
throw err;
|
package/dist/api/commit.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commit.js","sourceRoot":"","sources":["../../src/api/commit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAI5B,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,MAAM,UAAU,QAAQ;IACtB,OAAO,MAAM,IAAI,EAAE,EAAE,CAAC;AACxB,CAAC;AAED,MAAM,UAAU,OAAO;IACrB,OAAO,KAAK,IAAI,EAAE,EAAE,CAAC;AACvB,CAAC;AASD,MAAM,UAAU,aAAa,CAAC,MAAoB,EAAE,MAAoB;IACtE,MAAM,QAAQ,GAAa;QACzB,QAAQ,EAAE,UAAU;QACpB,MAAM,EAAE,CAAC;QACT,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,QAAQ,EAAE;QAC/B,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,GAAG,EAAE,MAAM,CAAC,GAAG;QACf,IAAI,EAAE;YACJ,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAChD,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACnD,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SAC7B;KACF,CAAC;IACF,IAAI,MAAM,CAAC,QAAQ,KAAK,SAAS;QAAE,QAAQ,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;IACvE,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,MAAoB,EACpB,QAAkB,EAClB,WAAW,GAAG,CAAC;IAEf,IAAI,OAAgB,CAAC;IACrB,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,WAAW,EAAE,OAAO,EAAE,EAAE,CAAC;QACvD,IAAI,CAAC;YACH,OAAO,MAAM,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QAC1C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,GAAG,YAAY,WAAW,IAAI,GAAG,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;gBAC3D,
|
|
1
|
+
{"version":3,"file":"commit.js","sourceRoot":"","sources":["../../src/api/commit.ts"],"names":[],"mappings":"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"}
|
package/dist/api/errors.js
CHANGED
|
@@ -60,6 +60,14 @@ export class UnexpectedResponseError extends Error {
|
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
62
|
export function errorFromBody(status, body) {
|
|
63
|
+
// The real backend's auth denials carry {detail} without a code field.
|
|
64
|
+
if (status === 403 &&
|
|
65
|
+
typeof body === 'object' &&
|
|
66
|
+
body !== null &&
|
|
67
|
+
!('code' in body) &&
|
|
68
|
+
typeof body.detail === 'string') {
|
|
69
|
+
return new JpatchError('FORBIDDEN', body.detail);
|
|
70
|
+
}
|
|
63
71
|
if (isJpatchErrorBody(body)) {
|
|
64
72
|
const { code, message, ...rest } = body;
|
|
65
73
|
if (code === 'HEAD_MISMATCH') {
|
package/dist/api/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/api/errors.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/api/errors.ts"],"names":[],"mappings":"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"}
|
package/dist/api/objects.d.ts
CHANGED
|
@@ -1,19 +1,27 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type Bootstrap, type RenderDomNode } from '../types.js';
|
|
2
2
|
import type { JpatchClient } from './client.js';
|
|
3
3
|
export interface PageEntity {
|
|
4
4
|
id: string;
|
|
5
5
|
name: string;
|
|
6
6
|
route: string;
|
|
7
7
|
root: RenderDomNode;
|
|
8
|
+
/** Creator page uuid — navigator route targets reference pages by this. */
|
|
9
|
+
uuid?: string;
|
|
8
10
|
}
|
|
9
11
|
export interface ComponentEntity {
|
|
10
12
|
id: string;
|
|
11
13
|
name: string;
|
|
12
14
|
root: RenderDomNode;
|
|
15
|
+
/** Creator component uuid — a page's `ComponentInstance` nodes link to it. */
|
|
16
|
+
uuid?: string;
|
|
13
17
|
}
|
|
14
18
|
export interface NavigationDocument {
|
|
15
|
-
|
|
16
|
-
|
|
19
|
+
/** Legacy/CLI route list. The real backend serves a navigator document
|
|
20
|
+
* (`data.navigators`) without this field — then route-tree codegen is
|
|
21
|
+
* skipped with a visible note; the raw doc is preserved in base. */
|
|
22
|
+
routes?: NavigationRoute[];
|
|
23
|
+
layouts?: Record<string, unknown>;
|
|
24
|
+
[k: string]: unknown;
|
|
17
25
|
}
|
|
18
26
|
export interface NavigationRoute {
|
|
19
27
|
id: string;
|
|
@@ -28,11 +36,18 @@ export interface StyleConfig {
|
|
|
28
36
|
sizing: Record<string, unknown>;
|
|
29
37
|
}
|
|
30
38
|
export type AssetIndex = Record<string, {
|
|
31
|
-
sha256
|
|
32
|
-
mime
|
|
39
|
+
sha256?: string;
|
|
40
|
+
mime?: string;
|
|
33
41
|
w?: number;
|
|
34
42
|
h?: number;
|
|
35
43
|
name?: string;
|
|
44
|
+
/** Real backend fields (dev): server-relative body URL + file metadata. */
|
|
45
|
+
link?: string;
|
|
46
|
+
file_name?: string;
|
|
47
|
+
extension?: string;
|
|
48
|
+
type?: string;
|
|
49
|
+
uuid?: string;
|
|
50
|
+
[k: string]: unknown;
|
|
36
51
|
}>;
|
|
37
52
|
export interface ProjectState {
|
|
38
53
|
head: string;
|
|
@@ -43,6 +58,8 @@ export interface ProjectState {
|
|
|
43
58
|
style: StyleConfig;
|
|
44
59
|
assets: AssetIndex;
|
|
45
60
|
}
|
|
61
|
+
/** Pages on the real backend carry no route; derive a stable one from the name. */
|
|
62
|
+
export declare function deriveRoute(name: string): string;
|
|
46
63
|
/** Cold bootstrap: walk the manifest and fetch every blob (RFC-0001 §6). */
|
|
47
64
|
export declare function fetchProjectState(client: JpatchClient, boot: Bootstrap): Promise<ProjectState>;
|
|
48
65
|
/**
|