@buoy-gg/solid 0.0.0-stage → 7.0.70

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,58 @@
1
+ PROPRIETARY SOFTWARE LICENSE
2
+
3
+ Copyright (c) 2024-present Buoy. All rights reserved.
4
+
5
+ This software and its source code are proprietary and confidential.
6
+
7
+ NOTICE: This is NOT open source software. This software is licensed,
8
+ not sold, and is protected by copyright laws and international treaties.
9
+
10
+ TERMS AND CONDITIONS:
11
+
12
+ 1. LICENSE GRANT
13
+ Subject to the terms of this Agreement and payment of applicable fees,
14
+ Buoy grants you a limited, non-exclusive, non-transferable license
15
+ to use the compiled software packages in your applications.
16
+
17
+ 2. RESTRICTIONS
18
+ You may NOT:
19
+ - Copy, modify, or distribute the source code
20
+ - Reverse engineer, decompile, or disassemble the software
21
+ - Remove or alter any proprietary notices or labels
22
+ - Sublicense, rent, lease, or lend the software
23
+ - Use the software to create competing products
24
+ - Share access credentials with unauthorized parties
25
+
26
+ 3. OWNERSHIP
27
+ React Buoy retains all right, title, and interest in the software,
28
+ including all intellectual property rights. This license does not
29
+ grant you any rights to trademarks or service marks.
30
+
31
+ 4. TERMINATION
32
+ This license is effective until terminated. Your rights under this
33
+ license will terminate automatically without notice if you fail to
34
+ comply with any of its terms. Upon termination, you must cease all
35
+ use and destroy all copies of the software.
36
+
37
+ 5. DISCLAIMER OF WARRANTIES
38
+ THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
39
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
40
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT.
41
+
42
+ 6. LIMITATION OF LIABILITY
43
+ IN NO EVENT SHALL BUOY BE LIABLE FOR ANY INDIRECT, INCIDENTAL,
44
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN
45
+ CONNECTION WITH THIS LICENSE OR THE USE OF THE SOFTWARE.
46
+
47
+ 7. GOVERNING LAW
48
+ This Agreement shall be governed by and construed in accordance with
49
+ the laws of the United States, without regard to its conflict of
50
+ law provisions.
51
+
52
+ For licensing inquiries and subscription information:
53
+ - Website: https://buoy.gg
54
+ - Email: AustinLovesWorking@gmail.com
55
+
56
+ Unauthorized reproduction or distribution of this software, or any
57
+ portion of it, may result in severe civil and criminal penalties,
58
+ and will be prosecuted to the maximum extent possible under the law.
package/README.md CHANGED
@@ -1,3 +1,99 @@
1
- # Temporary Holding Version
1
+ # Buoy for Solid
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
+ Buoy runs in Solid 1.9 apps built with Vite, as a beta.
4
+ Your app stays all Solid.
5
+ Buoy uses React for its own screens and brings it along.
6
+ The full guide is the [Solid page](https://buoy.gg/buoy/latest/docs/web/solid).
7
+
8
+ ## Install and sign in
9
+
10
+ Run these from your app folder:
11
+
12
+ ```sh
13
+ npm install --save-dev @buoy-gg/core @buoy-gg/solid @buoy-gg/network
14
+ npx buoy login
15
+ ```
16
+
17
+ Add more tools the same way.
18
+ Use the same version for all Buoy packages.
19
+ `buoy login` writes `VITE_BUOY_KEY` to a file Git ignores.
20
+
21
+ ## Set up
22
+
23
+ Add the Vite plugin:
24
+
25
+ ```ts
26
+ // vite.config.ts
27
+ import solid from 'vite-plugin-solid';
28
+ import { buoy } from '@buoy-gg/core/vite';
29
+
30
+ export default defineConfig({ plugins: [solid(), buoy()] });
31
+ ```
32
+
33
+ Put `<Buoy />` in your router's root, inside `QueryClientProvider`:
34
+
35
+ ```tsx
36
+ import { Buoy } from '@buoy-gg/solid';
37
+
38
+ function Layout(props) {
39
+ return (
40
+ <>
41
+ {props.children}
42
+ <Buoy />
43
+ </>
44
+ );
45
+ }
46
+
47
+ <Router root={Layout}>...</Router>
48
+ ```
49
+
50
+ That's all.
51
+ The plugin finds your tools and adds the early hook.
52
+ It leaves Buoy out of prod builds.
53
+ `<Buoy />` reads your key and starts Buoy after the first render.
54
+ It links Solid Router and Solid Query when you have them.
55
+ It stops Buoy when it goes away, so hot reload is safe.
56
+
57
+ ## Options
58
+
59
+ `<Buoy />` takes the same props as `mountBuoy` from `@buoy-gg/core/web`, plus these:
60
+
61
+ | Prop | What it does |
62
+ |---|---|
63
+ | `routes` | Your route config, so the Routes sitemap lists every page |
64
+ | `load` | Loads app settings with Buoy. Use a dev check so prod drops the file |
65
+ | `modules` | Your own tool list, in place of the plugin's |
66
+ | `enableInRelease` | Starts Buoy in a release build too. Set `buoy({ enableInRelease: true })` as well |
67
+ | `onMount` | Called with the stop function once Buoy is up |
68
+ | `onDestroy` | Called when Buoy stops |
69
+
70
+ `startBuoy(options)` starts Buoy with no component.
71
+ It can't read Solid context, so pass `queryClient` yourself.
72
+
73
+ ## Solid stores and signals
74
+
75
+ ```tsx
76
+ import { buoySolidSignal, buoySolidStore } from '@buoy-gg/solid/store';
77
+
78
+ <Buoy zustandStores={{
79
+ todos: buoySolidStore([todos, setTodos]),
80
+ count: buoySolidSignal([count, setCount]),
81
+ }} />
82
+ ```
83
+
84
+ They show in the Zustand tool.
85
+ You can read and edit them there.
86
+ An edit keeps the fields you did not change.
87
+
88
+ ## Entry points
89
+
90
+ | Import | Holds |
91
+ |---|---|
92
+ | `@buoy-gg/solid` | `<Buoy />`, `startBuoy` |
93
+ | `@buoy-gg/solid/register` | The early hook. The Vite plugin adds it for you |
94
+ | `@buoy-gg/solid/router` | `connectBuoyRouter`, for a router link by hand |
95
+ | `@buoy-gg/solid/store` | `buoySolidStore`, `buoySolidSignal` |
96
+ | `@buoy-gg/solid/highlights` | `connectBuoyHighlights`, for Highlight by hand |
97
+
98
+ Each entry has a `buoy-disabled` build that does nothing.
99
+ The Vite plugin picks it for prod builds.
package/lib/auto.d.ts ADDED
@@ -0,0 +1,15 @@
1
+ /** What `<Buoy />` links when the app has the packages for it. */
2
+ export interface BuoySolidLinks {
3
+ /** The Solid Query client from context. */
4
+ queryClient?: unknown;
5
+ /** Starts the Solid Router link. Returns its stop function. */
6
+ router?: () => Promise<() => void>;
7
+ }
8
+ /**
9
+ * Read the app's Solid Router and Solid Query context while `<Buoy />` sets
10
+ * up. The buoy() Vite plugin replaces this file with one that imports only
11
+ * the packages the app lists. Without the plugin, nothing is linked.
12
+ */
13
+ export declare function useBuoyLinks(_options: {
14
+ routes?: unknown;
15
+ }): BuoySolidLinks;
package/lib/auto.mjs ADDED
@@ -0,0 +1 @@
1
+ function n(o){return{}}export{n as useBuoyLinks};
@@ -0,0 +1,4 @@
1
+ import type { BuoyHighlightController } from '../highlights';
2
+ export declare function connectBuoyHighlights(_controller: BuoyHighlightController): () => void;
3
+ export declare function excludeFromHighlights(_owner: object | null | undefined): void;
4
+ export declare function isExcluded(_owner: object): boolean;
@@ -0,0 +1 @@
1
+ function t(n){return()=>{}}function e(n){}function i(n){return false}export{t as connectBuoyHighlights,e as excludeFromHighlights,i as isExcluded};
@@ -0,0 +1,5 @@
1
+ import type { BuoyOptions } from '../index';
2
+ /** The buoy-disabled build condition keeps no loader and no tools. */
3
+ export declare function Buoy(_props: BuoyOptions): null;
4
+ export declare function startBuoy(_options?: BuoyOptions): () => void;
5
+ export declare function isBuoyDevBuild(): boolean;
@@ -0,0 +1 @@
1
+ function n(u){return null}function t(u={}){return()=>{}}function o(){return false}export{n as Buoy,o as isBuoyDevBuild,t as startBuoy};
@@ -0,0 +1,4 @@
1
+ /** Keep the early entry inert when the build has disabled Buoy. */
2
+ export declare function registerBrowserNetwork(_options?: {
3
+ enableInRelease?: boolean;
4
+ }): boolean;
@@ -0,0 +1 @@
1
+ function r(e={}){return false}export{r as registerBrowserNetwork};
@@ -0,0 +1,4 @@
1
+ import type { BuoySolidRouterLink, SolidRouteDefinition } from '../router';
2
+ export declare function connectBuoyRouter(_link: BuoySolidRouterLink): () => void;
3
+ export declare function solidRouteTemplate(pattern: string): string;
4
+ export declare function solidRoutePaths(_routes: SolidRouteDefinition | SolidRouteDefinition[] | undefined, _parent?: string): string[];
@@ -0,0 +1 @@
1
+ function n(t){return()=>{}}function o(t){return t}function e(t,u=""){return[]}export{n as connectBuoyRouter,e as solidRoutePaths,o as solidRouteTemplate};
@@ -0,0 +1,6 @@
1
+ import type { SetStoreFunction } from 'solid-js/store';
2
+ import type { BuoyStoreApi } from '../store';
3
+ export declare function buoySolidStore<T extends object>([store]: [T, SetStoreFunction<T>]): BuoyStoreApi<T>;
4
+ export declare function buoySolidSignal<T>([get]: [() => T, (next: () => T) => unknown]): BuoyStoreApi<{
5
+ value: T;
6
+ }>;
@@ -0,0 +1 @@
1
+ function e(t){return{getState:t,getInitialState:t,setState(){},subscribe:()=>()=>{}}}function n([t]){return e(()=>t)}function o([t]){return e(()=>({value:t()}))}export{o as buoySolidSignal,n as buoySolidStore};
@@ -0,0 +1,24 @@
1
+ import { type SolidOwner } from './hooks';
2
+ export interface SolidRenderBatch {
3
+ host: HTMLElement;
4
+ name: string;
5
+ count: number;
6
+ }
7
+ export interface BuoyHighlightController {
8
+ isEnabled(): boolean;
9
+ subscribe(listener: (enabled: boolean) => void): () => void;
10
+ connectRenderSource(available: boolean): {
11
+ recordRenders(renders: SolidRenderBatch[]): void;
12
+ disconnect(): void;
13
+ };
14
+ }
15
+ /** Keep this owner and everything under it out of Highlight. */
16
+ export declare function excludeFromHighlights(owner: object | null | undefined): void;
17
+ export declare function isExcluded(owner: SolidOwner): boolean;
18
+ /**
19
+ * Feed Solid updates to Highlight Updates. Computations are wrapped only while
20
+ * Highlight is on; turning it on later wraps the ones that already exist. A
21
+ * wrapper never reads app state: it notes the computation, and the names and
22
+ * boxes are worked out in the next animation frame, after Solid has finished.
23
+ */
24
+ export declare function connectBuoyHighlights(controller: BuoyHighlightController): () => void;
@@ -0,0 +1 @@
1
+ var F="[data-buoy-root],[data-buoy-mount]";function P(){let e=new Set,t=r=>{for(let i of r){let a=i.target.nodeType===1?i.target:i.target.parentElement;a&&!a.closest(F)&&e.add(a)}},l=globalThis.MutationObserver,n=globalThis.document?.documentElement,o=l&&n?new l(t):void 0;return o?.observe(n,{subtree:true,childList:true,characterData:true,attributes:true}),{take(){o&&t(o.takeRecords());let r=new Set(e);return e.clear(),r},stop(){o?.disconnect(),e.clear()}}}function V(e,t){let l=e[0];for(let n of e.slice(1))for(;l!==t&&!l.contains(n);)l=l.parentElement??t;return l.getBoundingClientRect?l:t}function j(e,t,l){let n=new Map;for(let r of t){if(!r.isConnected)continue;let i;for(let{host:a}of e)a.contains(r)&&(!i||i.contains(a))&&(i=a);if(i){let a=n.get(i);a?a.push(r):n.set(i,[r])}}let o=new Map;for(let r of e){let i=n.get(r.host),a=l?.get(r.host),c=i?V(i,r.host):a?.isConnected&&r.host.contains(a)?a:r.host;i&&l?.set(r.host,c);let p=o.get(c);p?p.count+=r.count:o.set(c,{...r,host:c})}return[...o.values()]}import{$DEVCOMP as q,DEV as z}from"solid-js";var I=Symbol.for("buoy.solid.hooks");function M(){let e=globalThis;return e[I]??={chains:new WeakMap,roots:new Set,ownerListeners:new Set,installed:false}}function N(){let e=z?.hooks;return e&&"afterCreateOwner"in e?e:void 0}function $(e,t,l){let{chains:n}=M(),o=n.get(e);o||n.set(e,o=new Map);let r=o.get(t);if(!r){let a=new Set;r=a,o.set(t,a);let c=e[t],p=(...u)=>{c?.(...u);for(let h of a)try{h(...u)}catch(m){console.error("[Buoy]",m)}};Object.defineProperty(e,t,{configurable:true,enumerable:true,get:()=>p,set:u=>{u!==p&&(c=u)}})}r.add(l);let i=r;return()=>{i.delete(l)}}function G(){let e=N(),t=M();return e?(t.installed||(t.installed=true,$(e,"afterCreateOwner",l=>{let n=l;n.fn||t.roots.add(new WeakRef(n));for(let o of t.ownerListeners)o(n)})),true):false}function J(e){let{ownerListeners:t}=M();return t.add(e),()=>{t.delete(e)}}function K(){let{roots:e}=M(),t=[],l=new WeakSet,n=o=>{if(!l.has(o)){l.add(o),o.fn&&t.push(o);for(let r of o.owned??[])n(r)}};for(let o of e){let r=o.deref();if(!r){e.delete(o);continue}n(r)}return t}function k(e){for(let t=e;t;t=t.owner)if(t.component)return t}function x(e){let t=e.component?.name||e.name||"Anonymous";if(typeof e.component?.preload=="function"){let l=e.sourceMap?.find(n=>typeof n.value=="function"&&n.value[q])?.value?.name;l&&(t=l)}return t.replace(/^\[solid-refresh\]/,"")||"Anonymous"}var Q=new Set(["Show","For","Index","Switch","Match","Dynamic","Portal","ErrorBoundary","Suspense","SuspenseList","NoHydration","Hydration","provider","Provider"]);function U(e){for(let t=k(e);t;t=k(t.owner))if(!Q.has(x(t)))return t}function X(e){let t=(n,o)=>{if(!(o>6||n==null)){if(typeof HTMLElement<"u"&&n instanceof HTMLElement)return n.isConnected?n:void 0;if(typeof Text<"u"&&n instanceof Text)return n.parentElement?.isConnected?n.parentElement:void 0;if(Array.isArray(n))for(let r of n){let i=t(r,o+1);if(i)return i}}},l=[e];for(let n=0;n<l.length&&n<400;n++){let o=t(l[n].value,0);if(o)return o;l.push(...l[n].owned??[])}}var A=new WeakSet;function Y(e){e&&A.add(e)}function H(e){for(let t=e;t;t=t.owner)if(A.has(t))return true;return false}var E=new WeakMap;function _(e){let t=E.get(e);if(!t){let o=G(),r=e.connectRenderSource(o),i=new WeakMap,a=new WeakMap,c=new Set,p=new WeakSet,u=new Map,h,m=false,g=false,v,R=new WeakMap,O=()=>{if(h=void 0,m){u.clear();return}let s=new Map;for(let[d,w]of u){if(H(d))continue;let y=k(d),b=U(d);if(!y||!b)continue;let S=X(y);if(!S)continue;let L=s.get(S);L?L.count+=w:s.set(S,{host:S,name:x(b),count:w})}u.clear();let f=v?.take()??new Set;s.size&&r.recordRenders(j([...s.values()],f,R))},W=(s,f)=>{let d=s.fn;if(!d||i.has(s))return;f&&p.add(s),i.set(s,d),c.add(new WeakRef(s));let w=function(y){let b=d.call(this,y);return p.has(s)?p.delete(s):g&&a.get(s)===w&&(u.set(s,(u.get(s)??0)+1),h??=requestAnimationFrame(O)),b};a.set(s,w),s.fn=w},C=()=>{for(let s of c){let f=s.deref(),d=f&&i.get(f);!f||!d||(f.fn===a.get(f)&&(f.fn=d),i.delete(f),a.delete(f))}c.clear(),u.clear()},T=s=>{if(!(m||!o||s===g))if(g=s,v?.stop(),v=s?P():void 0,s)for(let f of K())W(f,false);else C()},B=o?J(s=>{g&&s.fn&&W(s,true)}):void 0,D=e.subscribe(T);T(e.isEnabled()),t={users:0,stop:()=>{m=true,B?.(),D(),g=false,v?.stop(),v=void 0,C(),h!==void 0&&cancelAnimationFrame(h),r.disconnect()}},E.set(e,t)}t.users++;let l=false,n=t;return()=>{l||(l=true,--n.users===0&&(n.stop(),E.delete(e)))}}export{_ as connectBuoyHighlights,Y as excludeFromHighlights,H as isExcluded};
package/lib/index.d.ts ADDED
@@ -0,0 +1,62 @@
1
+ import { useBuoyLinks } from '#buoy-solid-auto';
2
+ /** A tool's browser module, as its `/web` entry exports it. */
3
+ type Modules = Record<string, unknown>;
4
+ /**
5
+ * Buoy's props, kept here so a Solid app's TypeScript never loads the React
6
+ * types behind @buoy-gg/core. The common ones are named; the rest of
7
+ * `FloatingDevTools`' props pass through as they are.
8
+ */
9
+ export interface BuoyMountOptions {
10
+ environment?: 'local' | 'dev' | 'qa' | 'staging' | 'prod';
11
+ userRole?: 'admin' | 'internal' | 'user';
12
+ /** Defaults to VITE_BUOY_KEY, which `buoy login` writes. */
13
+ licenseKey?: string;
14
+ /** The app's TanStack Query client. Found from QueryClientProvider when left out. */
15
+ queryClient?: unknown;
16
+ /** Stores for the Zustand tool: vanilla Zustand stores, or buoySolidStore/buoySolidSignal. */
17
+ zustandStores?: Record<string, unknown>;
18
+ /** Custom tools made with createWebTool. */
19
+ apps?: unknown[];
20
+ requiredEnvVars?: unknown[];
21
+ requiredStorageKeys?: unknown[];
22
+ externalSync?: boolean | {
23
+ socketURL?: string;
24
+ deviceName?: string;
25
+ enableInRelease?: boolean;
26
+ };
27
+ sentryGetClient?: () => unknown;
28
+ [prop: string]: unknown;
29
+ }
30
+ export interface BuoyOptions extends BuoyMountOptions {
31
+ /** Start in a release build as well. App access rules still apply. */
32
+ enableInRelease?: boolean;
33
+ /** The tools to load. Defaults to every tool the buoy() Vite plugin found. */
34
+ modules?: Modules | (() => Promise<Modules>);
35
+ /** The app's route config or FileRoutes(), so the Routes sitemap lists every page. */
36
+ routes?: unknown;
37
+ /**
38
+ * Load app settings and links with Buoy, such as `apps` or `zustandStores`.
39
+ * Use a dev-only dynamic import here so a production build leaves them out.
40
+ */
41
+ load?: () => Promise<Omit<BuoyOptions, 'load' | 'enableInRelease'>>;
42
+ /** Called once Buoy is mounted. The stop function is safe to call twice. */
43
+ onMount?: (stop: () => void) => void;
44
+ /** Called when Buoy stops, to remove app hooks the loader added. */
45
+ onDestroy?: () => void;
46
+ }
47
+ /** Whether Buoy starts by default: the phone app's debug flag in a Capacitor shell, otherwise a dev build. */
48
+ export declare function isBuoyDevBuild(): boolean;
49
+ /**
50
+ * Mount Buoy with no component. It can't read Solid context, so pass
51
+ * `queryClient` yourself. Returns a stop function that is safe to call before
52
+ * Buoy has finished loading.
53
+ */
54
+ export declare function startBuoy(options?: BuoyOptions & {
55
+ links?: ReturnType<typeof useBuoyLinks>;
56
+ }): () => void;
57
+ /**
58
+ * Buoy for a Solid app. Put it inside `<Router>` (for example in its `root`)
59
+ * and inside `QueryClientProvider`, and it links both. It renders nothing.
60
+ */
61
+ export declare function Buoy(props: BuoyOptions): null;
62
+ export {};
package/lib/index.mjs ADDED
@@ -0,0 +1 @@
1
+ import{getOwner as P,onCleanup as U,onMount as q}from"solid-js";import{useBuoyLinks as x}from"#buoy-solid-auto";var F="[data-buoy-root],[data-buoy-mount]";function K(){let e=new Set,t=l=>{for(let i of l){let s=i.target.nodeType===1?i.target:i.target.parentElement;s&&!s.closest(F)&&e.add(s)}},r=globalThis.MutationObserver,n=globalThis.document?.documentElement,o=r&&n?new r(t):void 0;return o?.observe(n,{subtree:true,childList:true,characterData:true,attributes:true}),{take(){o&&t(o.takeRecords());let l=new Set(e);return e.clear(),l},stop(){o?.disconnect(),e.clear()}}}function N(e,t){let r=e[0];for(let n of e.slice(1))for(;r!==t&&!r.contains(n);)r=r.parentElement??t;return r.getBoundingClientRect?r:t}function I(e,t,r){let n=new Map;for(let l of t){if(!l.isConnected)continue;let i;for(let{host:s}of e)s.contains(l)&&(!i||i.contains(s))&&(i=s);if(i){let s=n.get(i);s?s.push(l):n.set(i,[l])}}let o=new Map;for(let l of e){let i=n.get(l.host),s=r?.get(l.host),d=i?N(i,l.host):s?.isConnected&&l.host.contains(s)?s:l.host;i&&r?.set(l.host,d);let a=o.get(d);a?a.count+=l.count:o.set(d,{...l,host:d})}return[...o.values()]}import{$DEVCOMP as Y,DEV as j}from"solid-js";var z=Symbol.for("buoy.solid.hooks");function C(){let e=globalThis;return e[z]??={chains:new WeakMap,roots:new Set,ownerListeners:new Set,installed:false}}function G(){let e=j?.hooks;return e&&"afterCreateOwner"in e?e:void 0}function $(e,t,r){let{chains:n}=C(),o=n.get(e);o||n.set(e,o=new Map);let l=o.get(t);if(!l){let s=new Set;l=s,o.set(t,s);let d=e[t],a=(...c)=>{d?.(...c);for(let h of s)try{h(...c)}catch(g){console.error("[Buoy]",g)}};Object.defineProperty(e,t,{configurable:true,enumerable:true,get:()=>a,set:c=>{c!==a&&(d=c)}})}l.add(r);let i=l;return()=>{i.delete(r)}}function J(){let e=G(),t=C();return e?(t.installed||(t.installed=true,$(e,"afterCreateOwner",r=>{let n=r;n.fn||t.roots.add(new WeakRef(n));for(let o of t.ownerListeners)o(n)})),true):false}function Q(e){let{ownerListeners:t}=C();return t.add(e),()=>{t.delete(e)}}function X(){let{roots:e}=C(),t=[],r=new WeakSet,n=o=>{if(!r.has(o)){r.add(o),o.fn&&t.push(o);for(let l of o.owned??[])n(l)}};for(let o of e){let l=o.deref();if(!l){e.delete(o);continue}n(l)}return t}function T(e){for(let t=e;t;t=t.owner)if(t.component)return t}function L(e){let t=e.component?.name||e.name||"Anonymous";if(typeof e.component?.preload=="function"){let r=e.sourceMap?.find(n=>typeof n.value=="function"&&n.value[Y])?.value?.name;r&&(t=r)}return t.replace(/^\[solid-refresh\]/,"")||"Anonymous"}var Z=new Set(["Show","For","Index","Switch","Match","Dynamic","Portal","ErrorBoundary","Suspense","SuspenseList","NoHydration","Hydration","provider","Provider"]);function ee(e){for(let t=T(e);t;t=T(t.owner))if(!Z.has(L(t)))return t}function te(e){let t=(n,o)=>{if(!(o>6||n==null)){if(typeof HTMLElement<"u"&&n instanceof HTMLElement)return n.isConnected?n:void 0;if(typeof Text<"u"&&n instanceof Text)return n.parentElement?.isConnected?n.parentElement:void 0;if(Array.isArray(n))for(let l of n){let i=t(l,o+1);if(i)return i}}},r=[e];for(let n=0;n<r.length&&n<400;n++){let o=t(r[n].value,0);if(o)return o;r.push(...r[n].owned??[])}}var A=new WeakSet;function ne(e){e&&A.add(e)}function oe(e){for(let t=e;t;t=t.owner)if(A.has(t))return true;return false}var W=new WeakMap;function re(e){let t=W.get(e);if(!t){let o=J(),l=e.connectRenderSource(o),i=new WeakMap,s=new WeakMap,d=new Set,a=new WeakSet,c=new Map,h,g=false,v=false,p,b=new WeakMap,E=()=>{if(h=void 0,g){c.clear();return}let u=new Map;for(let[w,y]of c){if(oe(w))continue;let M=T(w),m=ee(w);if(!M||!m)continue;let _=te(M);if(!_)continue;let R=u.get(_);R?R.count+=y:u.set(_,{host:_,name:L(m),count:y})}c.clear();let f=p?.take()??new Set;u.size&&l.recordRenders(I([...u.values()],f,b))},D=(u,f)=>{let w=u.fn;if(!w||i.has(u))return;f&&a.add(u),i.set(u,w),d.add(new WeakRef(u));let y=function(M){let m=w.call(this,M);return a.has(u)?a.delete(u):v&&s.get(u)===y&&(c.set(u,(c.get(u)??0)+1),h??=requestAnimationFrame(E)),m};s.set(u,y),u.fn=y},O=()=>{for(let u of d){let f=u.deref(),w=f&&i.get(f);!f||!w||(f.fn===s.get(f)&&(f.fn=w),i.delete(f),s.delete(f))}d.clear(),c.clear()},B=u=>{if(!(g||!o||u===v))if(v=u,p?.stop(),p=u?K():void 0,u)for(let f of X())D(f,false);else O()},k=o?Q(u=>{v&&u.fn&&D(u,true)}):void 0,S=e.subscribe(B);B(e.isEnabled()),t={users:0,stop:()=>{g=true,k?.(),S(),v=false,p?.stop(),p=void 0,O(),h!==void 0&&cancelAnimationFrame(h),l.disconnect()}},W.set(e,t)}t.users++;let r=false,n=t;return()=>{r||(r=true,--n.users===0&&(n.stop(),W.delete(e)))}}function le(){try{return import.meta.env.VITE_BUOY_KEY||void 0}catch{return}}function H(){if(typeof window>"u")return false;let e=window.Capacitor,t=false;try{t=e?.isNativePlatform?.()===true}catch{t=false}return t?e?.DEBUG===true:typeof __DEV__<"u"?!!__DEV__:process.env.NODE_ENV!=="production"}function V(e={}){if(typeof window>"u"||typeof document>"u")return()=>{};let{enableInRelease:t,modules:r,routes:n,onMount:o,onDestroy:l,load:i,links:s={},...d}=e;if(!H()&&!t)return()=>{};globalThis.__BUOY_FRAMEWORK__="solid";let a=false,c,h=[];l&&h.push(l);let g=()=>{for(let p of h.splice(0).reverse())try{p()}catch(b){console.error("[Buoy]",b)}};(async()=>{let p=i?await i():{},{modules:b,onDestroy:E,onMount:D,routes:O,...B}=p;if(E){if(a){E();return}h.push(E)}if(a)return;let k={...d,...B},S=b??r,u=typeof S=="function"?await S():S??(await import("@buoy-gg/core/web/installed-tools")).installedTools;if(a)return;let f=u["highlight-updates"]?.HighlightUpdatesController;if(f)try{h.push(re(f))}catch(m){console.warn("[Buoy] Highlight Updates already has a render source, so Solid updates are not shown.",m)}if(s.router){let m=await s.router();if(a){m();return}h.push(m)}let{mountBuoy:w}=await import("@buoy-gg/core/web");if(a)return;let y=k.queryClient??s.queryClient,M=k.licenseKey??le();c=w({...k,modules:u,...y?{queryClient:y}:{},...M?{licenseKey:M}:{}}),o?.(v)})().catch(p=>{g(),console.error("[Buoy] Buoy did not start.",p)});function v(){if(a)return;a=true;let p=c;c=void 0,p?.(),g()}return v}function ue(e){if(typeof window>"u")return null;let t=P();ne(t);let r=x({routes:e.routes}),n;return q(()=>{n=V({...e,links:r})}),U(()=>n?.()),null}export{ue as Buoy,H as isBuoyDevBuild,V as startBuoy};
@@ -0,0 +1,2 @@
1
+ import '@buoy-gg/core/web/register-network';
2
+ export { registerBrowserNetwork } from '@buoy-gg/core/web/register-network';
@@ -0,0 +1 @@
1
+ import"@buoy-gg/core/web/register-network";import{$DEVCOMP as b,DEV as E}from"solid-js";var C=Symbol.for("buoy.solid.hooks");function w(){let t=globalThis;return t[C]??={chains:new WeakMap,roots:new Set,ownerListeners:new Set,installed:false}}function T(){let t=E?.hooks;return t&&"afterCreateOwner"in t?t:void 0}function W(t,e,a){let{chains:r}=w(),o=r.get(t);o||r.set(t,o=new Map);let s=o.get(e);if(!s){let c=new Set;s=c,o.set(e,c);let h=t[e],l=(...f)=>{h?.(...f);for(let m of c)try{m(...f)}catch(n){console.error("[Buoy]",n)}};Object.defineProperty(t,e,{configurable:true,enumerable:true,get:()=>l,set:f=>{f!==l&&(h=f)}})}s.add(a);let d=s;return()=>{d.delete(a)}}function v(){let t=T(),e=w();return t?(e.installed||(e.installed=true,W(t,"afterCreateOwner",a=>{let r=a;r.fn||e.roots.add(new WeakRef(r));for(let o of e.ownerListeners)o(r)})),true):false}function D(t){let{ownerListeners:e}=w();return e.add(t),()=>{e.delete(t)}}function L(){let{roots:t}=w(),e=[],a=new WeakSet,r=o=>{if(!a.has(o)){a.add(o),o.fn&&e.push(o);for(let s of o.owned??[])r(s)}};for(let o of t){let s=o.deref();if(!s){t.delete(o);continue}r(s)}return e}function S(t){for(let e=t;e;e=e.owner)if(e.component)return e}function g(t){let e=t.component?.name||t.name||"Anonymous";if(typeof t.component?.preload=="function"){let a=t.sourceMap?.find(r=>typeof r.value=="function"&&r.value[b])?.value?.name;a&&(e=a)}return e.replace(/^\[solid-refresh\]/,"")||"Anonymous"}var x=new Set(["Show","For","Index","Switch","Match","Dynamic","Portal","ErrorBoundary","Suspense","SuspenseList","NoHydration","Hydration","provider","Provider"]);function O(t){for(let e=S(t);e;e=S(e.owner))if(!x.has(g(e)))return e}function A(t){let e=(r,o)=>{if(!(o>6||r==null)){if(typeof HTMLElement<"u"&&r instanceof HTMLElement)return r.isConnected?r:void 0;if(typeof Text<"u"&&r instanceof Text)return r.parentElement?.isConnected?r.parentElement:void 0;if(Array.isArray(r))for(let s of r){let d=e(s,o+1);if(d)return d}}},a=[t];for(let r=0;r<a.length&&r<400;r++){let o=e(a[r].value,0);if(o)return o;a.push(...a[r].owned??[])}}var k;function B(){if(k&&Date.now()-k.at<300)return k.map;let t=new WeakMap,{roots:e}=w(),a=new WeakSet,r=[];for(let o of e){let s=o.deref();s&&r.push(s)}for(let o=0;o<r.length&&o<2e4;o++){let s=r[o];if(!a.has(s)){if(a.add(s),s.component&&!x.has(g(s))){let d=A(s);d&&t.set(d,g(s))}r.push(...s.owned??[])}}return k={at:Date.now(),map:t},t}function R(t){let e=B();for(let a=t;a;a=a.parentElement){let r=e.get(a);if(r)return r}}var _=new WeakSet;function H(t){for(let e=t;e;e=e.owner)if(_.has(e))return true;return false}var N=15;function P(){let t=null;return{isSupported:()=>v(),start(){t?.();let e=new Map,a=new Map,r=new Map,o=new WeakSet,s=0,d=false,c=(l,f)=>{let m=l.fn;if(!m||a.has(l))return;f&&o.add(l),a.set(l,m);let n=function(u){let y=performance.now(),p=m.call(this,u);if(r.get(l)!==n||H(l))return p;let i=performance.now()-y,M=e.get(l)??{mount:0,updates:0,ms:0,maxMs:0};return o.has(l)?(o.delete(l),M.mount+=1):M.updates+=1,M.ms+=i,M.maxMs=Math.max(M.maxMs,i),e.set(l,M),d||(d=true,s+=1,queueMicrotask(()=>{d=false})),p};r.set(l,n),l.fn=n};for(let l of L())c(l,false);let h=D(l=>{l.fn&&c(l,true)});t=()=>{h();for(let[n,u]of a)n.fn===r.get(n)&&(n.fn=u);let l=new Map;for(let[n,u]of e){let y=O(n);if(!y)continue;let p=g(y),i=l.get(p)??{name:p,renders:0,totalMs:0,maxMs:0,avgMs:0,causes:{}};i.renders+=u.mount+u.updates,i.totalMs+=u.ms,i.maxMs=Math.max(i.maxMs,u.maxMs),u.mount&&(i.causes.mount=(i.causes.mount??0)+u.mount),u.updates&&(i.causes.hooks=(i.causes.hooks??0)+u.updates),l.set(p,i)}let f=[...l.values()];for(let n of f)n.totalMs=Math.round(n.totalMs*100)/100,n.maxMs=Math.round(n.maxMs*100)/100,n.avgMs=n.renders?Math.round(n.totalMs/n.renders*100)/100:0;let m={mount:0,hooks:0};for(let n of f)m.mount+=n.causes.mount??0,m.hooks+=n.causes.hooks??0;return{totalCommits:s,totalRenders:f.reduce((n,u)=>n+u.renders,0),capturedDurations:true,totalRenderMs:Math.round(f.reduce((n,u)=>n+u.totalMs,0)*100)/100,causes:m,topComponents:f.sort((n,u)=>u.renders-n.renders||u.totalMs-n.totalMs).slice(0,N)}}},stop(){let e=t;return t=null,e?e():null}}}import{registerBrowserNetwork as F}from"@buoy-gg/core/web/register-network";globalThis.__BUOY_FRAMEWORK__="solid";v();globalThis[Symbol.for("buoy.dom.componentName")]=R;globalThis[Symbol.for("buoy.framework.renderCapture")]=P();export{F as registerBrowserNetwork};
@@ -0,0 +1,43 @@
1
+ import { type Owner } from 'solid-js';
2
+ /** The parts of Solid Router's location and matches the adapter reads. */
3
+ export interface SolidRouterLocation {
4
+ readonly pathname: string;
5
+ readonly search: string;
6
+ }
7
+ export interface SolidRouteMatch {
8
+ params: Record<string, string | undefined>;
9
+ route: {
10
+ pattern: string;
11
+ info?: Record<string, unknown>;
12
+ };
13
+ }
14
+ /** A route definition as Solid Router and SolidStart's FileRoutes give them. */
15
+ export interface SolidRouteDefinition {
16
+ path?: string | string[];
17
+ children?: SolidRouteDefinition | SolidRouteDefinition[];
18
+ component?: unknown;
19
+ }
20
+ export interface BuoySolidRouterLink {
21
+ /** `useLocation()`, read inside `<Router>`. */
22
+ location: SolidRouterLocation;
23
+ /** `useCurrentMatches()`, read inside `<Router>`. */
24
+ matches: () => SolidRouteMatch[];
25
+ /** `useNavigate()`, read inside `<Router>`. */
26
+ navigate: (to: string, options?: {
27
+ replace?: boolean;
28
+ }) => void;
29
+ /** The app's route config or FileRoutes(), for the sitemap. Without it, routes are added as they're seen. */
30
+ routes?: SolidRouteDefinition | SolidRouteDefinition[];
31
+ /** The owner to run under. Defaults to the current one. */
32
+ owner?: Owner | null;
33
+ }
34
+ /** Solid Router patterns in the Routes tool's form: `:id` → `[id]`, `*rest` → `[...rest]`. */
35
+ export declare function solidRouteTemplate(pattern: string): string;
36
+ /** Every page path in a route config, as templates. */
37
+ export declare function solidRoutePaths(routes: SolidRouteDefinition | SolidRouteDefinition[] | undefined, parent?: string): string[];
38
+ /**
39
+ * Report Solid Router navigations to the Routes tool with their names and
40
+ * params, and let the tool's Go button and the MCP navigate through the
41
+ * router. Raw history capture stops adding its own events while this runs.
42
+ */
43
+ export declare function connectBuoyRouter({ location, matches, navigate, routes, owner }: BuoySolidRouterLink): () => void;
package/lib/router.mjs ADDED
@@ -0,0 +1 @@
1
+ import{createRoot as x,createEffect as D,getOwner as L,runWithOwner as N,untrack as T}from"solid-js";import{claimBrowserRouteEvents as U,registerBrowserRoutes as S,routeObserver as W}from"@buoy-gg/route-events/web";import{registerBrowserRouter as C}from"@buoy-gg/shared-ui/web/utils";function $(r){return`/${r}`.replace(/\/+/g,"/").replace(/(.)\/$/,"$1").replace(/:([^/?]+)\??/g,"[$1]").replace(/\*([^/]*)/g,(o,e)=>`[...${e||"rest"}]`)}function y(r,o=""){return(r===void 0?[]:Array.isArray(r)?r:[r]).flatMap(e=>(e.path===void 0?[""]:Array.isArray(e.path)?e.path:[e.path]).flatMap(c=>{let n=`${o}/${c}`.replace(/\/+/g,"/"),s=e.children===void 0?[]:y(e.children,n);return[...e.component&&!s.length?[$(n)]:[],...s]}))}function K({location:r,matches:o,navigate:e,routes:c,owner:n=L()}){let s=U(),i=new Set(y(c)),u=S([...i]),E=C({push:t=>e(t),replace:t=>e(t,{replace:true}),back:()=>history.back()}),B,m,P,M=(t,l,a)=>{let p=`${t}${l}`;if(p===P)return;P=p;let f=a[a.length-1],h=f?.route.pattern??t,d=$(h);f&&!i.has(d)&&(i.add(d),u(),u=S([...i]));let g={};for(let[w,R]of new URLSearchParams(l))g[w]=R;for(let w of a)for(let[R,k]of Object.entries(w.params))k!==void 0&&(g[R]=k);let O=f?.route.info,j=typeof O?.name=="string"?O.name:h,v=Date.now();W.emit({pathname:t,params:g,segments:d.split("/").filter(Boolean),routeName:j,matchedPath:h,previousPathname:B,timestamp:v,timeSincePrevious:m===void 0?void 0:v-m}),B=t,m=v},b;N(n??null,()=>x(t=>{b=t,D(()=>{let l=r.pathname,a=r.search,p=o();T(()=>M(l,a,p))})}));let A=true;return()=>{A&&(A=false,b?.(),u(),s(),E())}}export{K as connectBuoyRouter,y as solidRoutePaths,$ as solidRouteTemplate};
package/lib/store.d.ts ADDED
@@ -0,0 +1,20 @@
1
+ import { type SetStoreFunction } from 'solid-js/store';
2
+ /** What Buoy's Zustand tool reads and writes. Pass it in `zustandStores`. */
3
+ export interface BuoyStoreApi<T> {
4
+ getState(): T;
5
+ getInitialState(): T;
6
+ setState(partial: Partial<T> | ((state: T) => Partial<T>), replace?: boolean): void;
7
+ subscribe(listener: (state: T, previous: T) => void): () => void;
8
+ }
9
+ /**
10
+ * Show a Solid store in Buoy's Zustand tool. Edits from the tool merge into
11
+ * the store with `reconcile`, so fields the edit left out stay as they are.
12
+ */
13
+ export declare function buoySolidStore<T extends object>([store, setStore]: [T, SetStoreFunction<T>]): BuoyStoreApi<T>;
14
+ /**
15
+ * Show a signal in Buoy's Zustand tool as `{ value }`, since the tool edits
16
+ * fields of an object, not a bare value.
17
+ */
18
+ export declare function buoySolidSignal<T>([get, set]: [() => T, (next: () => T) => unknown]): BuoyStoreApi<{
19
+ value: T;
20
+ }>;
package/lib/store.mjs ADDED
@@ -0,0 +1 @@
1
+ import{createEffect as w,createRoot as A,untrack as y}from"solid-js";import{reconcile as h,unwrap as v}from"solid-js/store";function i(t,e=new WeakMap){if(t===null||typeof t!="object")return t;if(t instanceof Date)return new Date(t.getTime());if(e.has(t))return e.get(t);if(Array.isArray(t)){let n=[];e.set(t,n);for(let o of t)n.push(i(o,e));return n}let r={};e.set(t,r);for(let n of Object.keys(t))r[n]=i(t[n],e);return r}function p(t,e=new WeakSet){if(!(t===null||typeof t!="object"||e.has(t))){e.add(t);for(let r of Object.keys(t))p(t[r],e)}}function g(t,e,r){let n=new Set,o=i(y(t)),j=o,c=false,l,b=(f,u)=>{for(let a of[...n])a(f,u)},S=()=>l?o:o=i(y(t)),k=()=>A(f=>{l=f;let u=true;w(()=>{if(r(),u){u=false;return}if(c)return;let a=o;o=i(y(t)),b(o,a)})});return{getState:S,getInitialState:()=>j,setState(f,u){let a=S(),s=typeof f=="function"?f(a):f,d=u||s===null||typeof s!="object"||Array.isArray(s)?s:{...a,...s},m=a;c=true;try{e(i(d))}finally{c=false}o=d,b(o,m)},subscribe(f){return n.add(f),l||k(),()=>{n.delete(f),n.size||(l?.(),l=void 0)}}}}function W([t,e]){return g(()=>v(t),r=>e(h(r)),()=>p(t))}function x([t,e]){return g(()=>({value:t()}),r=>e(()=>r.value),()=>{p(t())})}export{x as buoySolidSignal,W as buoySolidStore};
package/package.json CHANGED
@@ -1,6 +1,91 @@
1
1
  {
2
2
  "name": "@buoy-gg/solid",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "7.0.70",
4
+ "description": "Run Buoy in a Solid app.",
5
+ "type": "module",
6
+ "exports": {
7
+ ".": {
8
+ "types": "./lib/index.d.ts",
9
+ "buoy-disabled": "./lib/disabled/index.mjs",
10
+ "default": "./lib/index.mjs"
11
+ },
12
+ "./register": {
13
+ "types": "./lib/register.d.ts",
14
+ "buoy-disabled": "./lib/disabled/register.mjs",
15
+ "default": "./lib/register.mjs"
16
+ },
17
+ "./router": {
18
+ "types": "./lib/router.d.ts",
19
+ "buoy-disabled": "./lib/disabled/router.mjs",
20
+ "default": "./lib/router.mjs"
21
+ },
22
+ "./store": {
23
+ "types": "./lib/store.d.ts",
24
+ "buoy-disabled": "./lib/disabled/store.mjs",
25
+ "default": "./lib/store.mjs"
26
+ },
27
+ "./highlights": {
28
+ "types": "./lib/highlights.d.ts",
29
+ "buoy-disabled": "./lib/disabled/highlights.mjs",
30
+ "default": "./lib/highlights.mjs"
31
+ },
32
+ "./package.json": "./package.json"
33
+ },
34
+ "imports": {
35
+ "#buoy-solid-auto": {
36
+ "types": "./lib/auto.d.ts",
37
+ "default": "./lib/auto.mjs"
38
+ }
39
+ },
40
+ "types": "./lib/index.d.ts",
41
+ "files": [
42
+ "lib",
43
+ "README.md"
44
+ ],
45
+ "sideEffects": [
46
+ "./lib/register.mjs",
47
+ "./lib/disabled/register.mjs"
48
+ ],
49
+ "dependencies": {
50
+ "react": "^19.2.0",
51
+ "react-dom": "^19.2.0",
52
+ "react-native-web": "^0.21.2",
53
+ "@buoy-gg/shared-ui": "^7.0.70",
54
+ "@buoy-gg/core": "^7.0.70"
55
+ },
56
+ "peerDependencies": {
57
+ "solid-js": ">=1.8 <2"
58
+ },
59
+ "peerDependenciesMeta": {
60
+ "@solidjs/router": {
61
+ "optional": true
62
+ },
63
+ "@tanstack/solid-query": {
64
+ "optional": true
65
+ },
66
+ "@buoy-gg/route-events": {
67
+ "optional": true
68
+ },
69
+ "@buoy-gg/zustand": {
70
+ "optional": true
71
+ },
72
+ "@buoy-gg/highlight-updates": {
73
+ "optional": true
74
+ }
75
+ },
76
+ "devDependencies": {
77
+ "@solid-devtools/debugger": "0.28.1",
78
+ "@solidjs/router": "1.0.0",
79
+ "@tanstack/solid-query": "5.104.5",
80
+ "esbuild": "^0.25.0",
81
+ "jsdom": "^26.1.0",
82
+ "solid-js": "1.9.17",
83
+ "typescript": "~5.8.3",
84
+ "vitest": "^3.2.0",
85
+ "@buoy-gg/route-events": "^7.0.70"
86
+ },
87
+ "scripts": {
88
+ "build": "node build.mjs && node ../../scripts/minify-lib.mjs && node ../../scripts/assert-minified.mjs",
89
+ "test": "vitest run --config vitest.config.mjs"
90
+ }
6
91
  }