@acornly/react 0.0.0-stage → 0.3.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 Free Solo
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 CHANGED
@@ -1,3 +1,17 @@
1
- # Temporary Holding Version
1
+ # @acornly/react
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ React 18 and 19 bindings for the [Acornly SDK](../sdk): a provider that starts one instance after mount and destroys it on unmount, and hooks that read it. It renders no UI of its own; pass the SDK's `builtInUi` for pins, cards and the toolbar, or draw notes yourself.
4
+
5
+ ```tsx
6
+ <AcornlyProvider
7
+ config={() => ({ adapter, scope: "app:my-site", user })}
8
+ deps={async () => ({ ui: (await import("@acornly/sdk/ui")).builtInUi })}
9
+ >
10
+ <App />
11
+ </AcornlyProvider>
12
+ ```
13
+
14
+ - `useAcornly()` gives `{ status, ctx, error }`, with `status` `"loading"`, `"ready"` or `"error"`.
15
+ - `useNotes(options)` returns `ctx.list(options)` and renders again as notes and anchors change; when the document switches, the old notes go at once and the new ones appear as they are anchored.
16
+
17
+ `@acornly/sdk` and `react` are peer dependencies. With React Server Components, render the provider from your own `"use client"` component (its props hold functions); the module is marked `"use client"` so importing it from a server module works. Server rendering is safe: `config` and `deps` are read in an effect, so the server renders the loading state and never touches the DOM. Import the built-in UI inside `deps`, as above, since it needs a DOM as soon as it loads. See [React in the getting-started guide](../../docs/getting-started.md#react).
@@ -0,0 +1,59 @@
1
+ import { type ReactElement, type ReactNode } from "react";
2
+ import { Acornly, type AcornlyConfig, type InitDeps, type ListedAnnotation, type ListOptions } from "@acornly/sdk";
3
+ /** The provider's instance: `ctx` is set once `Acornly.init` has loaded the notes. */
4
+ export type AcornlyState = {
5
+ status: "loading";
6
+ ctx: null;
7
+ error: null;
8
+ } | {
9
+ status: "ready";
10
+ ctx: Acornly;
11
+ error: null;
12
+ } | {
13
+ status: "error";
14
+ ctx: null;
15
+ error: unknown;
16
+ };
17
+ export interface AcornlyProviderProps {
18
+ /**
19
+ * The SDK config, or a function that returns it (or a promise of it). The provider reads it in
20
+ * the effect that starts the instance, after its first render in the browser, so a function can
21
+ * build the adapter there and read refs (`root: mainRef.current`), and on the server it is never
22
+ * called. Later changes are not picked up: give the provider a new `key` to start over with
23
+ * another config. The effect runs again, with the first render's values, only when React
24
+ * remounts it (StrictMode in development, or an `<Activity>` shown again). So `user` must read
25
+ * live state (the auth client, or a ref kept current), not a value captured at render.
26
+ */
27
+ config: AcornlyConfig | (() => AcornlyConfig | Promise<AcornlyConfig>);
28
+ /**
29
+ * `init`'s second argument, or a function that returns it (or a promise of it), read with
30
+ * `config`. The SDK's built-in UI needs a DOM as soon as it is imported, so a page that renders
31
+ * on the server imports it here: `deps={async () => ({ ui: (await import("@acornly/sdk/ui"))
32
+ * .builtInUi })}`. A client-only page can pass `{ ui: builtInUi }`.
33
+ */
34
+ deps?: InitDeps | (() => InitDeps | Promise<InitDeps>);
35
+ children?: ReactNode;
36
+ }
37
+ /**
38
+ * Starts one Acornly instance for the components under it and destroys it on unmount. It
39
+ * renders only its children: pass the SDK's `builtInUi` in `deps` for its own pins, cards and
40
+ * toolbar, or leave it out and draw notes with `useNotes`. Nothing touches the DOM during render,
41
+ * so it is safe in server rendering, where the state stays `loading`.
42
+ */
43
+ export declare function AcornlyProvider({ config, deps, children }: AcornlyProviderProps): ReactElement;
44
+ /**
45
+ * The provider's instance and whether it is ready. `ctx` is null while loading, on the server and
46
+ * when `init` failed (`error` says why); once ready it is the instance, for `add`, `focus`,
47
+ * `setPlacement` and the rest of the SDK's API.
48
+ */
49
+ export declare function useAcornly(): AcornlyState;
50
+ /**
51
+ * The current document's notes, as `ctx.list(options)` returns them, oldest first, and kept up to
52
+ * date: notes added, edited or removed here or by sync, and anchors found, lost or looked for
53
+ * again. When the document switches (navigation or `setDocument`) the old document's notes go at
54
+ * once and the new ones appear as they are anchored. A silent anchor refresh (the SDK re-saving
55
+ * where a note's text now is) does not render again. Empty until the instance is ready, and on the
56
+ * server.
57
+ */
58
+ export declare function useNotes(options?: ListOptions): ListedAnnotation[];
59
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAQL,KAAK,YAAY,EACjB,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AACf,OAAO,EACL,OAAO,EACP,KAAK,aAAa,EAElB,KAAK,QAAQ,EACb,KAAK,gBAAgB,EACrB,KAAK,WAAW,EACjB,MAAM,cAAc,CAAC;AAEtB,sFAAsF;AACtF,MAAM,MAAM,YAAY,GACpB;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,GAAG,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,IAAI,CAAA;CAAE,GAC7C;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,GAAG,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,IAAI,CAAA;CAAE,GAC9C;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,GAAG,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAAC;AAEnD,MAAM,WAAW,oBAAoB;IACnC;;;;;;;;OAQG;IACH,MAAM,EAAE,aAAa,GAAG,CAAC,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC;IACvE;;;;;OAKG;IACH,IAAI,CAAC,EAAE,QAAQ,GAAG,CAAC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;IACvD,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAwDD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,oBAAoB,GAAG,YAAY,CAqC9F;AAQD;;;;GAIG;AACH,wBAAgB,UAAU,IAAI,YAAY,CAEzC;AAKD;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CAAC,OAAO,GAAE,WAAgB,GAAG,gBAAgB,EAAE,CAsBtE"}
package/dist/index.js ADDED
@@ -0,0 +1,137 @@
1
+ "use client";
2
+ import { createContext, createElement, useContext, useEffect, useMemo, useState, useSyncExternalStore, } from "react";
3
+ import { Acornly, } from "@acornly/sdk";
4
+ const LOADING = { status: "loading", ctx: null, error: null };
5
+ const HiveContext = createContext(null);
6
+ HiveContext.displayName = "Acornly";
7
+ /** Everything that can change what `list()` returns. */
8
+ const NOTE_EVENTS = [
9
+ "annotation:created",
10
+ "annotation:updated",
11
+ "annotation:removed",
12
+ "anchor:resolved",
13
+ "anchor:orphaned",
14
+ "anchor:pending",
15
+ "document:loading",
16
+ "document:change",
17
+ ];
18
+ /**
19
+ * Counts the instance's note changes, for `useSyncExternalStore`. It listens from the moment the
20
+ * instance is ready, before any component reads `list()`, so no change falls between a render and
21
+ * that component's subscription.
22
+ */
23
+ class NoteVersions {
24
+ version = 0;
25
+ listeners = new Set();
26
+ stops;
27
+ constructor(ctx) {
28
+ this.stops = NOTE_EVENTS.map((event) => ctx.on(event, () => {
29
+ this.version++;
30
+ for (const fn of [...this.listeners])
31
+ fn();
32
+ }));
33
+ }
34
+ subscribe = (fn) => {
35
+ this.listeners.add(fn);
36
+ return () => this.listeners.delete(fn);
37
+ };
38
+ getVersion = () => this.version;
39
+ stop() {
40
+ for (const stop of this.stops.splice(0))
41
+ stop();
42
+ this.listeners.clear();
43
+ }
44
+ }
45
+ /**
46
+ * Starts one Acornly instance for the components under it and destroys it on unmount. It
47
+ * renders only its children: pass the SDK's `builtInUi` in `deps` for its own pins, cards and
48
+ * toolbar, or leave it out and draw notes with `useNotes`. Nothing touches the DOM during render,
49
+ * so it is safe in server rendering, where the state stays `loading`.
50
+ */
51
+ export function AcornlyProvider({ config, deps, children }) {
52
+ const [shared, setShared] = useState({ state: LOADING, notes: null });
53
+ // The first render's config and deps win, as documented, also when React remounts the effect.
54
+ const [initial] = useState(() => ({ config, deps }));
55
+ useEffect(() => {
56
+ const { config, deps } = initial;
57
+ let cancelled = false;
58
+ let ctx = null;
59
+ let notes = null;
60
+ (async () => {
61
+ const resolved = typeof config === "function" ? await config() : config;
62
+ if (cancelled)
63
+ return;
64
+ const parts = typeof deps === "function" ? await deps() : deps;
65
+ if (cancelled)
66
+ return;
67
+ const started = await Acornly.init(resolved, parts);
68
+ if (cancelled) {
69
+ started.destroy();
70
+ return;
71
+ }
72
+ ctx = started;
73
+ notes = new NoteVersions(started);
74
+ setShared({ state: { status: "ready", ctx: started, error: null }, notes });
75
+ })().catch((error) => {
76
+ if (!cancelled)
77
+ setShared({ state: { status: "error", ctx: null, error }, notes: null });
78
+ });
79
+ return () => {
80
+ cancelled = true;
81
+ notes?.stop();
82
+ ctx?.destroy();
83
+ // A remount that keeps state (an <Activity> shown again) starts over from loading, never
84
+ // with the destroyed instance or the last start's error.
85
+ setShared((s) => (s.state.status === "loading" ? s : { state: LOADING, notes: null }));
86
+ };
87
+ }, [initial]);
88
+ return createElement(HiveContext.Provider, { value: shared }, children);
89
+ }
90
+ function useShared(hook) {
91
+ const shared = useContext(HiveContext);
92
+ if (!shared)
93
+ throw new Error(`${hook} must be used inside <AcornlyProvider>`);
94
+ return shared;
95
+ }
96
+ /**
97
+ * The provider's instance and whether it is ready. `ctx` is null while loading, on the server and
98
+ * when `init` failed (`error` says why); once ready it is the instance, for `add`, `focus`,
99
+ * `setPlacement` and the rest of the SDK's API.
100
+ */
101
+ export function useAcornly() {
102
+ return useShared("useAcornly").state;
103
+ }
104
+ const noSubscribe = () => () => { };
105
+ const zero = () => 0;
106
+ /**
107
+ * The current document's notes, as `ctx.list(options)` returns them, oldest first, and kept up to
108
+ * date: notes added, edited or removed here or by sync, and anchors found, lost or looked for
109
+ * again. When the document switches (navigation or `setDocument`) the old document's notes go at
110
+ * once and the new ones appear as they are anchored. A silent anchor refresh (the SDK re-saving
111
+ * where a note's text now is) does not render again. Empty until the instance is ready, and on the
112
+ * server.
113
+ */
114
+ export function useNotes(options = {}) {
115
+ const { state, notes } = useShared("useNotes");
116
+ const version = useSyncExternalStore(notes?.subscribe ?? noSubscribe, notes?.getVersion ?? zero, zero);
117
+ const { ctx } = state;
118
+ const { motivation, tag } = options;
119
+ // `version` is not read inside, but it is what changes when the list does.
120
+ return useMemo(() => {
121
+ if (!ctx)
122
+ return [];
123
+ const filter = {};
124
+ if (motivation !== undefined)
125
+ filter.motivation = motivation;
126
+ if (tag !== undefined)
127
+ filter.tag = tag;
128
+ try {
129
+ return ctx.list(filter);
130
+ }
131
+ catch {
132
+ // Destroyed as the provider unmounts.
133
+ return [];
134
+ }
135
+ }, [ctx, version, motivation, tag]);
136
+ }
137
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,38 @@
1
1
  {
2
2
  "name": "@acornly/react",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "0.3.0",
4
+ "description": "React provider and hooks around the Acornly SDK, for React 18 and 19",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/postagilab/acornly.git",
9
+ "directory": "packages/react"
10
+ },
11
+ "type": "module",
12
+ "sideEffects": false,
13
+ "exports": {
14
+ ".": {
15
+ "types": "./dist/index.d.ts",
16
+ "import": "./dist/index.js"
17
+ }
18
+ },
19
+ "files": [
20
+ "dist"
21
+ ],
22
+ "peerDependencies": {
23
+ "react": "^18.0.0 || ^19.0.0",
24
+ "@acornly/sdk": "^0.3.0"
25
+ },
26
+ "devDependencies": {
27
+ "@types/react": "^19.2.0",
28
+ "@types/react-dom": "^19.2.0",
29
+ "react": "^19.2.0",
30
+ "react-dom": "^19.2.0",
31
+ "@acornly/core": "0.3.0",
32
+ "@acornly/sdk": "0.3.0",
33
+ "@acornly/adapter-memory": "0.2.1"
34
+ },
35
+ "publishConfig": {
36
+ "access": "public"
37
+ }
6
38
  }