Skip to content

Commit 08ce9ef

Browse files
committed
Publish presentation web app
1 parent a305b8e commit 08ce9ef

20 files changed

+2159
-168
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ build
22
legacy
33
node_modules
44
coverage
5+
!docs

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55

66
Get the JSONPath at any cursor position in JSON text. Perfect for editor plugins, JSON tools, and autocomplete features.
77

8+
[**Try the interactive demo**](https://7ph.github.io/json-cursor-path/)
9+
10+
![demo](docs-src/public/demo.gif)
11+
812
## Getting started
913

1014
1. Install `json-cursor-path`

docs-src/index.html

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<link rel="icon" type="image/png" href="/favicon.png" />
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7+
<title>json-cursor-path — Get the JSONPath at any cursor position</title>
8+
<meta name="description" content="Lightweight TypeScript library to get the JSONPath at any cursor position in JSON text. ~1KB, O(n), supports malformed JSON." />
9+
</head>
10+
<body>
11+
<div id="app"></div>
12+
<script type="module" src="/src/main.ts"></script>
13+
</body>
14+
</html>

docs-src/public/demo.gif

600 KB
Loading

docs-src/src/App.vue

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<template>
2+
<div class="min-h-screen">
3+
<AppHeader />
4+
5+
<main class="max-w-5xl mx-auto px-4 sm:px-6 lg:px-8 py-12 space-y-20">
6+
<InteractiveDemo />
7+
<FeaturesSection />
8+
<ApiReference />
9+
</main>
10+
11+
<footer class="border-t border-slate-800 py-8 text-center text-slate-500 text-sm">
12+
<p>
13+
<a
14+
href="https://github.com/7PH/json-cursor-path"
15+
class="hover:text-teal-400 transition-colors"
16+
>
17+
GitHub
18+
</a>
19+
&middot;
20+
<a
21+
href="https://github.com/7PH/json-cursor-path/issues"
22+
class="hover:text-teal-400 transition-colors"
23+
>
24+
Report an issue
25+
</a>
26+
&middot;
27+
<a
28+
href="https://www.npmjs.com/package/json-cursor-path"
29+
class="hover:text-teal-400 transition-colors"
30+
>
31+
npm
32+
</a>
33+
</p>
34+
</footer>
35+
</div>
36+
</template>
37+
38+
<script setup lang="ts">
39+
import AppHeader from '@/components/AppHeader.vue';
40+
import InteractiveDemo from '@/components/InteractiveDemo.vue';
41+
import FeaturesSection from '@/components/FeaturesSection.vue';
42+
import ApiReference from '@/components/ApiReference.vue';
43+
</script>
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
<template>
2+
<section id="api">
3+
<h2 class="text-2xl font-bold text-white mb-6">API Reference</h2>
4+
5+
<div class="space-y-8">
6+
<!-- Constructor -->
7+
<div class="bg-slate-800 rounded-lg p-5">
8+
<h3 class="text-lg font-semibold text-white mb-2 font-mono">
9+
new JsonCursorPath(code, options?)
10+
</h3>
11+
<p class="text-slate-400 text-sm mb-3">
12+
Create a new parser instance for the given JSON text.
13+
</p>
14+
<div class="overflow-x-auto">
15+
<table class="w-full text-sm text-left">
16+
<thead>
17+
<tr class="border-b border-slate-700 text-slate-400">
18+
<th class="py-2 pr-4">Parameter</th>
19+
<th class="py-2 pr-4">Type</th>
20+
<th class="py-2">Description</th>
21+
</tr>
22+
</thead>
23+
<tbody class="text-slate-300">
24+
<tr class="border-b border-slate-700/50">
25+
<td class="py-2 pr-4 font-mono text-teal-400">code</td>
26+
<td class="py-2 pr-4 font-mono">string</td>
27+
<td class="py-2">The JSON text to parse</td>
28+
</tr>
29+
<tr>
30+
<td class="py-2 pr-4 font-mono text-teal-400">options?</td>
31+
<td class="py-2 pr-4 font-mono">JsonCursorPathOptions</td>
32+
<td class="py-2">Optional configuration</td>
33+
</tr>
34+
</tbody>
35+
</table>
36+
</div>
37+
</div>
38+
39+
<!-- get() -->
40+
<div class="bg-slate-800 rounded-lg p-5">
41+
<h3 class="text-lg font-semibold text-white mb-2 font-mono">
42+
.get(cursorPosition, returnRawPath?)
43+
</h3>
44+
<p class="text-slate-400 text-sm mb-3">
45+
Get the JSONPath at the specified cursor position. Returns <code class="text-teal-400">null</code> if the cursor is outside any JSON value.
46+
</p>
47+
<highlightjs language="typescript" :code="getOverloads" />
48+
<div class="overflow-x-auto mt-3">
49+
<table class="w-full text-sm text-left">
50+
<thead>
51+
<tr class="border-b border-slate-700 text-slate-400">
52+
<th class="py-2 pr-4">Parameter</th>
53+
<th class="py-2 pr-4">Type</th>
54+
<th class="py-2">Description</th>
55+
</tr>
56+
</thead>
57+
<tbody class="text-slate-300">
58+
<tr class="border-b border-slate-700/50">
59+
<td class="py-2 pr-4 font-mono text-teal-400">cursorPosition</td>
60+
<td class="py-2 pr-4 font-mono">number</td>
61+
<td class="py-2">Zero-based character offset in the JSON text</td>
62+
</tr>
63+
<tr>
64+
<td class="py-2 pr-4 font-mono text-teal-400">returnRawPath?</td>
65+
<td class="py-2 pr-4 font-mono">boolean</td>
66+
<td class="py-2">
67+
If <code class="text-teal-400">true</code>, returns a <code class="font-mono">PathToCursor</code> array.
68+
Defaults to <code class="text-teal-400">false</code> (returns a JSONPath string).
69+
</td>
70+
</tr>
71+
</tbody>
72+
</table>
73+
</div>
74+
</div>
75+
76+
<!-- rawPathToString() -->
77+
<div class="bg-slate-800 rounded-lg p-5">
78+
<h3 class="text-lg font-semibold text-white mb-2 font-mono">
79+
.rawPathToString(path)
80+
</h3>
81+
<p class="text-slate-400 text-sm">
82+
Converts a <code class="font-mono">PathToCursor</code> array to a JSONPath string.
83+
</p>
84+
</div>
85+
86+
<!-- Types -->
87+
<div class="bg-slate-800 rounded-lg p-5">
88+
<h3 class="text-lg font-semibold text-white mb-2">Types</h3>
89+
<highlightjs language="typescript" :code="typesCode" />
90+
</div>
91+
92+
<!-- Options -->
93+
<div class="bg-slate-800 rounded-lg p-5">
94+
<h3 class="text-lg font-semibold text-white mb-2 font-mono">
95+
JsonCursorPathOptions
96+
</h3>
97+
<div class="overflow-x-auto">
98+
<table class="w-full text-sm text-left">
99+
<thead>
100+
<tr class="border-b border-slate-700 text-slate-400">
101+
<th class="py-2 pr-4">Option</th>
102+
<th class="py-2 pr-4">Type</th>
103+
<th class="py-2 pr-4">Default</th>
104+
<th class="py-2">Description</th>
105+
</tr>
106+
</thead>
107+
<tbody class="text-slate-300">
108+
<tr>
109+
<td class="py-2 pr-4 font-mono text-teal-400">specifyStringIndex</td>
110+
<td class="py-2 pr-4 font-mono">boolean</td>
111+
<td class="py-2 pr-4 font-mono">false</td>
112+
<td class="py-2">
113+
When enabled, if the cursor is inside a string value, a <code class="font-mono">string</code> path entry is appended with the character index within that string.
114+
</td>
115+
</tr>
116+
</tbody>
117+
</table>
118+
</div>
119+
</div>
120+
121+
<!-- When get() returns null -->
122+
<div class="bg-slate-800 rounded-lg p-5">
123+
<h3 class="text-lg font-semibold text-white mb-2">
124+
When does <code class="font-mono text-teal-400">.get()</code> return <code class="font-mono text-teal-400">null</code>?
125+
</h3>
126+
<ul class="list-disc list-inside text-slate-400 text-sm space-y-1">
127+
<li>Cursor is before the root value (e.g., on leading whitespace)</li>
128+
<li>Cursor is after the root value (e.g., on trailing whitespace)</li>
129+
<li>Cursor is between values (e.g., on whitespace between object entries)</li>
130+
<li>The JSON text is empty</li>
131+
</ul>
132+
</div>
133+
</div>
134+
</section>
135+
</template>
136+
137+
<script setup lang="ts">
138+
const getOverloads = `// Returns a JSONPath string
139+
.get(cursorPosition: number): string | null
140+
141+
// Returns a raw path array
142+
.get(cursorPosition: number, true): PathToCursor | null`;
143+
144+
const typesCode = `type PathEntry =
145+
| { type: 'object'; key: string }
146+
| { type: 'array'; index: number }
147+
| { type: 'string'; index: number };
148+
149+
type PathToCursor = PathEntry[];
150+
151+
type JsonCursorPathOptions = {
152+
specifyStringIndex: boolean;
153+
};`;
154+
</script>
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<template>
2+
<header class="border-b border-slate-800">
3+
<div class="max-w-5xl mx-auto px-4 sm:px-6 lg:px-8 py-12 text-center">
4+
<h1 class="text-4xl sm:text-5xl font-bold text-white mb-3">
5+
<span class="text-teal-400">{}</span> json-cursor-path
6+
</h1>
7+
<p class="text-lg text-slate-400 mb-6 max-w-2xl mx-auto">
8+
Get the JSONPath at any cursor position in JSON text
9+
</p>
10+
<div class="flex flex-wrap justify-center gap-3 mb-6">
11+
<img
12+
alt="Coverage"
13+
src="https://img.shields.io/badge/coverage-100%25-brightgreen?style=flat-square"
14+
/>
15+
<img
16+
alt="Bundle size"
17+
src="https://img.shields.io/badge/size-~1KB-blue?style=flat-square"
18+
/>
19+
<img
20+
alt="TypeScript"
21+
src="https://img.shields.io/badge/types-TypeScript-3178c6?style=flat-square"
22+
/>
23+
<img
24+
alt="License"
25+
src="https://img.shields.io/badge/license-MIT-green?style=flat-square"
26+
/>
27+
</div>
28+
<div class="flex justify-center gap-4">
29+
<a
30+
href="https://github.com/7PH/json-cursor-path"
31+
class="inline-flex items-center gap-2 px-4 py-2 bg-slate-800 hover:bg-slate-700 rounded-lg text-sm font-medium transition-colors"
32+
>
33+
GitHub
34+
</a>
35+
<a
36+
href="https://www.npmjs.com/package/json-cursor-path"
37+
class="inline-flex items-center gap-2 px-4 py-2 bg-teal-600 hover:bg-teal-500 text-white rounded-lg text-sm font-medium transition-colors"
38+
>
39+
npm
40+
</a>
41+
</div>
42+
</div>
43+
</header>
44+
</template>
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
<template>
2+
<section id="features">
3+
<h2 class="text-2xl font-bold text-white mb-6">Features</h2>
4+
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
5+
<div
6+
v-for="feature in features"
7+
:key="feature.title"
8+
class="bg-slate-800 rounded-lg p-5"
9+
>
10+
<div class="text-2xl mb-2">{{ feature.icon }}</div>
11+
<h3 class="text-white font-semibold mb-1">{{ feature.title }}</h3>
12+
<p class="text-slate-400 text-sm">{{ feature.description }}</p>
13+
</div>
14+
</div>
15+
</section>
16+
17+
<section id="install">
18+
<h2 class="text-2xl font-bold text-white mb-4">Install & Usage</h2>
19+
<div class="space-y-4">
20+
<highlightjs language="shell" code="npm install json-cursor-path" />
21+
<highlightjs language="typescript" :code="usageCode" />
22+
</div>
23+
</section>
24+
</template>
25+
26+
<script setup lang="ts">
27+
const features = [
28+
{
29+
icon: '\u26A1',
30+
title: 'O(n) Performance',
31+
description: 'Single-pass parsing from start to cursor position. No full JSON parse required.',
32+
},
33+
{
34+
icon: '\uD83D\uDCE6',
35+
title: '~1KB Bundle Size',
36+
description: 'Minimal footprint. No dependencies. Tree-shakeable ES module.',
37+
},
38+
{
39+
icon: '\uD83D\uDD12',
40+
title: 'TypeScript Types',
41+
description: 'Full type definitions included. Typed path entries and options.',
42+
},
43+
{
44+
icon: '\uD83D\uDD27',
45+
title: 'Malformed JSON',
46+
description: 'Gracefully handles incomplete or malformed JSON without throwing errors.',
47+
},
48+
{
49+
icon: '\uD83D\uDCCD',
50+
title: 'String Index Tracking',
51+
description: 'Optionally track the character position within JSON string values.',
52+
},
53+
{
54+
icon: '\uD83D\uDD00',
55+
title: 'Dual Output Modes',
56+
description: 'Get results as a JSONPath string or a structured path array.',
57+
},
58+
];
59+
60+
const usageCode = `import { JsonCursorPath } from 'json-cursor-path';
61+
62+
const json = '{"store": {"books": [{"title": "Gatsby"}]}}';
63+
const parser = new JsonCursorPath(json);
64+
65+
// Get JSONPath string at cursor position 35
66+
parser.get(35); // "$.store.books[0].title"
67+
68+
// Get raw path array
69+
parser.get(35, true); // [{type: "object", key: "store"}, ...]`;
70+
</script>

0 commit comments

Comments
 (0)