diff --git a/spec.md b/spec.md index 5f40029..e6d5a23 100644 --- a/spec.md +++ b/spec.md @@ -82,6 +82,8 @@ subject.cid -- "bafyreicuxyp5rmsrqsf3v63ww6gc3j7q6cp7qyk6bv47c3bqkj2gzswiqq" Object field names can be arbitrary strings, so RecordPath needs to disambiguate its own syntax when fields contain syntax characters. +The backslash is the conventional escape character in many languages and systems, but as per the URL-unreserved character constraint in section 1, it cannot be used here. The exclamation mark ! serves as its replacement. + RecordPath has six syntax characters, which must be escaped by a preceeding `!` if they appear in a field name in the path. | Literal | Escaped | Syntax hint | -- 2.51.2 From 367dacb9ee85e7545b02fa9140471df23f2a9d00 Mon Sep 17 00:00:00 2001 From: phil Date: Thu, 16 Apr 2026 20:02:19 -0400 Subject: [PATCH 2/3] link to playground --- readme.md | 2 ++ ref-impl-rust/Cargo.lock | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 2b31448..bf16c28 100644 --- a/readme.md +++ b/readme.md @@ -4,6 +4,8 @@ a textual notation to locate fields within atproto records see [spec.md](./spec.md) +try it out in [the playground](https://microcosm.tngl.io/RecordPath/) + --- diff --git a/ref-impl-rust/Cargo.lock b/ref-impl-rust/Cargo.lock index 0abd081..decffcd 100644 --- a/ref-impl-rust/Cargo.lock +++ b/ref-impl-rust/Cargo.lock @@ -34,7 +34,7 @@ dependencies = [ [[package]] name = "recordpath" -version = "0.0.1" +version = "0.0.2" dependencies = [ "serde", "serde_json", -- 2.51.2 From 136ef8cc4e647d879824e38ec56d48a07606fa81 Mon Sep 17 00:00:00 2001 From: phil Date: Fri, 17 Apr 2026 12:12:56 -0400 Subject: [PATCH 3/3] display mode for preview values --- playground/src/lib/JsonDisplay.svelte | 193 ++++++++++++++++++++++++++ playground/src/routes/+page.svelte | 51 +++++-- 2 files changed, 235 insertions(+), 9 deletions(-) create mode 100644 playground/src/lib/JsonDisplay.svelte diff --git a/playground/src/lib/JsonDisplay.svelte b/playground/src/lib/JsonDisplay.svelte new file mode 100644 index 0000000..f2b4bea --- /dev/null +++ b/playground/src/lib/JsonDisplay.svelte @@ -0,0 +1,193 @@ + + +
+ {@render objectBlock(record, '', activeSegs, 0)} +
+ + +{#snippet objectBlock(obj: Record, prefix: string, segs: Segment[], depth: number)} +
+ {'{'} +
+ {@render objectEntries(obj, prefix, segs, depth + 1)} +
+ {'}'} +
+{/snippet} + + +{#snippet objectEntries(obj: Record, prefix: string, segs: Segment[], depth: number)} + {@const entries = Object.entries(obj)} + {#each entries as [key, child], idx} + {@const path = kp(prefix, key)} + {@const onPath = segs.length > 0 && segs[0].key === key} + {@const seg = onPath ? segs[0] : null} + {@const rest = onPath ? segs.slice(1) : []} + {@const comma = idx < entries.length - 1 ? ',' : ''} + {@const matched = onPath && rest.length === 0 && seg !== null && seg.qualifiers.length === 0} + + {#if isLeaf(child)} + +
+ : + {comma} +
+ {:else if Array.isArray(child)} + +
+ : [ +
+ {@render arrayEntries(child, path, seg, rest, depth + 1)} +
+ ]{comma} +
+ {:else} + + {@const isUnion = isObj(child) && !!child.$type} + {@const qualPrefix = isUnion ? `${path}{${(child as Record).$type}}` : path} + {@const cSegs = childSegs(onPath, seg, rest, child)} +
+ : {'{'} +
+ {@render objectEntries(child as Record, qualPrefix, cSegs, depth + 1)} +
+ {'}'}{comma} +
+ {/if} + {/each} +{/snippet} + + +{#snippet arrayEntries(arr: unknown[], prefix: string, seg: Segment | null, restSegs: Segment[], depth: number)} + {#each arr as elem, idx} + {@const comma = idx < arr.length - 1 ? ',' : ''} + {@const onPath = elemOnPath(seg, elem)} + {@const eSegs = onPath ? restSegs : []} + {@const ePrefix = isObj(elem) && elem.$type ? `${prefix}[${elem.$type}]` : `${prefix}[]`} + {@const matched = onPath && eSegs.length === 0} + + {#if isLeaf(elem)} +
+ {formatLeaf(elem)}{comma} +
+ {:else if Array.isArray(elem)} +
+ [ +
+ {@render arrayEntries(elem, ePrefix, null, [], depth + 1)} +
+ ]{comma} +
+ {:else} + {@const isUnion = isObj(elem) && !!elem.$type} + {@const qualPrefix = isUnion ? `${prefix}[${(elem as Record).$type}]` : `${prefix}[]`} +
+ {'{'} +
+ {@render objectEntries(elem as Record, qualPrefix, eSegs, depth + 1)} +
+ {'}'}{comma} +
+ {/if} + {/each} +{/snippet} diff --git a/playground/src/routes/+page.svelte b/playground/src/routes/+page.svelte index c9cf0de..869706d 100644 --- a/playground/src/routes/+page.svelte +++ b/playground/src/routes/+page.svelte @@ -1,5 +1,6 @@