bun-plugin-stx 0.0.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.
@@ -0,0 +1,42 @@
1
+ export declare const version: unknown;
2
+ export declare interface HydrationConfig {
3
+ autoStart?: boolean
4
+ preload?: 'none' | 'eager' | 'lazy'
5
+ }
6
+ export declare type IslandHandlers = Record<string, () => Promise<any>>
7
+
8
+ export type HydrationFunction = (element: HTMLElement, props: any) => void | Promise<void>
9
+
10
+ const isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined'
11
+
12
+ async function hydrateIsland(
13
+ element: HTMLElement,
14
+ name: string,
15
+ handler: () => Promise<any>,
16
+ ): Promise<void> {
17
+ if (!isBrowser) return
18
+
19
+ try {
20
+ const id = element.getAttribute('data-island-id')
21
+ const propsScript = document.querySelector(`script[data-island-props="${id}"]`) as HTMLScriptElement
22
+ const props = propsScript ? JSON.parse(propsScript.textContent || '{}') : {}
23
+
24
+ const module = await handler()
25
+ const hydrateFn: HydrationFunction = module.default || module.hydrate
26
+
27
+ if (typeof hydrateFn !== 'function') {
28
+ console.error(`Island handler for "${name}" does not export a valid hydration function`)
29
+ return
30
+ }
31
+
32
+ await hydrateFn(element, props)
33
+
34
+ element.setAttribute('data-hydrated', 'true')
35
+ }
36
+ catch (error) {
37
+ console.error(`Failed to hydrate island "${name}":`, error)
38
+ }
39
+ }
40
+ export declare function hydrateIslands(handlers: IslandHandlers): void;
41
+ export declare function preloadIslandHandlers(handlers: IslandHandlers): void;
42
+ export declare function initIslands(handlers: IslandHandlers, config: HydrationConfig = {}): void;
package/dist/client.js ADDED
@@ -0,0 +1,144 @@
1
+ // @bun
2
+ var __create = Object.create;
3
+ var __getProtoOf = Object.getPrototypeOf;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __toESM = (mod, isNodeMode, target) => {
8
+ target = mod != null ? __create(__getProtoOf(mod)) : {};
9
+ const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
10
+ for (let key of __getOwnPropNames(mod))
11
+ if (!__hasOwnProp.call(to, key))
12
+ __defProp(to, key, {
13
+ get: () => mod[key],
14
+ enumerable: true
15
+ });
16
+ return to;
17
+ };
18
+ var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
19
+ var __export = (target, all) => {
20
+ for (var name in all)
21
+ __defProp(target, name, {
22
+ get: all[name],
23
+ enumerable: true,
24
+ configurable: true,
25
+ set: (newValue) => all[name] = () => newValue
26
+ });
27
+ };
28
+ var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
29
+ var __require = import.meta.require;
30
+
31
+ // src/client.ts
32
+ var version = "1.0.0";
33
+ var isBrowser = typeof window !== "undefined" && typeof document !== "undefined";
34
+ async function hydrateIsland(element, name, handler) {
35
+ if (!isBrowser)
36
+ return;
37
+ try {
38
+ const id = element.getAttribute("data-island-id");
39
+ const propsScript = document.querySelector(`script[data-island-props="${id}"]`);
40
+ const props = propsScript ? JSON.parse(propsScript.textContent || "{}") : {};
41
+ const module = await handler();
42
+ const hydrateFn = module.default || module.hydrate;
43
+ if (typeof hydrateFn !== "function") {
44
+ console.error(`Island handler for "${name}" does not export a valid hydration function`);
45
+ return;
46
+ }
47
+ await hydrateFn(element, props);
48
+ element.setAttribute("data-hydrated", "true");
49
+ } catch (error) {
50
+ console.error(`Failed to hydrate island "${name}":`, error);
51
+ }
52
+ }
53
+ function hydrateIslands(handlers) {
54
+ if (!isBrowser)
55
+ return;
56
+ const islands = document.querySelectorAll("[data-island]");
57
+ const lazyIslands = [];
58
+ islands.forEach((island) => {
59
+ const name = island.getAttribute("data-island");
60
+ const priority = island.getAttribute("data-priority") || "lazy";
61
+ if (!name || !handlers[name] || island.getAttribute("data-hydrated") === "true") {
62
+ return;
63
+ }
64
+ if (priority === "eager") {
65
+ hydrateIsland(island, name, handlers[name]);
66
+ } else {
67
+ lazyIslands.push([island, name]);
68
+ }
69
+ });
70
+ if (lazyIslands.length > 0 && "IntersectionObserver" in window) {
71
+ const observer = new IntersectionObserver((entries) => {
72
+ entries.forEach((entry) => {
73
+ if (entry.isIntersecting) {
74
+ const element = entry.target;
75
+ const name = element.getAttribute("data-island");
76
+ if (name && handlers[name] && element.getAttribute("data-hydrated") !== "true") {
77
+ hydrateIsland(element, name, handlers[name]);
78
+ observer.unobserve(element);
79
+ }
80
+ }
81
+ });
82
+ }, {
83
+ rootMargin: "200px",
84
+ threshold: 0
85
+ });
86
+ lazyIslands.forEach(([element]) => {
87
+ observer.observe(element);
88
+ });
89
+ } else {
90
+ setTimeout(() => {
91
+ lazyIslands.forEach(([element, name]) => {
92
+ if (element.getAttribute("data-hydrated") !== "true") {
93
+ hydrateIsland(element, name, handlers[name]);
94
+ }
95
+ });
96
+ }, 1000);
97
+ }
98
+ }
99
+ function preloadIslandHandlers(handlers) {
100
+ if (!isBrowser)
101
+ return;
102
+ Object.entries(handlers).forEach(([name, getHandler]) => {
103
+ try {
104
+ const handlerString = getHandler.toString();
105
+ const moduleMatch = handlerString.match(/import\(['"](.+)['"]\)/);
106
+ if (moduleMatch && moduleMatch[1]) {
107
+ const link = document.createElement("link");
108
+ link.rel = "modulepreload";
109
+ link.href = moduleMatch[1];
110
+ link.setAttribute("data-island-module", name);
111
+ document.head.appendChild(link);
112
+ }
113
+ } catch (error) {
114
+ console.warn(`Failed to preload island handler for "${name}":`, error);
115
+ }
116
+ });
117
+ }
118
+ function initIslands(handlers, config = {}) {
119
+ if (!isBrowser)
120
+ return;
121
+ const defaultConfig = {
122
+ autoStart: true,
123
+ preload: "lazy"
124
+ };
125
+ const options = { ...defaultConfig, ...config };
126
+ if (options.preload !== "none") {
127
+ preloadIslandHandlers(handlers);
128
+ }
129
+ if (options.autoStart) {
130
+ if (document.readyState === "loading") {
131
+ document.addEventListener("DOMContentLoaded", () => {
132
+ hydrateIslands(handlers);
133
+ });
134
+ } else {
135
+ hydrateIslands(handlers);
136
+ }
137
+ }
138
+ }
139
+ export {
140
+ version,
141
+ preloadIslandHandlers,
142
+ initIslands,
143
+ hydrateIslands
144
+ };
@@ -0,0 +1,5 @@
1
+ import type { BunPlugin } from 'bun';
2
+
3
+ export declare let plugin: BunPlugin;
4
+
5
+ export default plugin;