From 976a29b7d768807842d93c1ebacb616df0a459b4 Mon Sep 17 00:00:00 2001 From: Eli Ribble Date: Sat, 21 Mar 2026 02:04:11 +0000 Subject: [PATCH] Create a working sample of an AlpineJS hello world --- README.md | 9 + flake.nix | 9 +- html/template/sync/template-test.html | 16 +- ts/main.ts | 23 +- ts/vendor/alpine-3.15.8.d.ts | 1 + ts/vendor/alpinejs-3.15.8.js | 3748 +++++++++++++++++++++++++ 6 files changed, 3795 insertions(+), 11 deletions(-) create mode 100644 ts/vendor/alpine-3.15.8.d.ts create mode 100644 ts/vendor/alpinejs-3.15.8.js diff --git a/README.md b/README.md index 2c2ff996..5197d3ef 100644 --- a/README.md +++ b/README.md @@ -84,6 +84,15 @@ This uses [goose](https://github.com/pressly/goose). You can use the goose comma > GOOSE_DRIVER=postgres GOOSE_DBSTRING="dbname=nidus-sync sslmode=disable" goose up ``` +### typescript + +You can generate the TypeScript with: + +``` +esbuild ts/main.ts --bundle --outfile=html/static/bundle.js --format=iife --minify +``` + +The only page that works right now is `https://sync.nidus.cloud/template-test` ### watchexec For iterating on styles diff --git a/flake.nix b/flake.nix index aaa13c43..623d1199 100644 --- a/flake.nix +++ b/flake.nix @@ -11,15 +11,15 @@ flake-utils.lib.eachDefaultSystem (system: let pkgs = nixpkgs.legacyPackages.${system}; - projPkg = proj.packages.${system}.default; + projPkg = proj.packages.${system}.default; # Override pkgs.proj with your custom proj customPkgs = pkgs // { proj = proj.packages.${system}.default; }; package = pkgs.callPackage ./default.nix { - proj = projPkg; - }; + proj = projPkg; + }; in { packages.default = package; @@ -31,7 +31,7 @@ pkgs.air pkgs.autoprefixer pkgs.dart-sass - pkgs.esbuild + pkgs.esbuild pkgs.go pkgs.goose pkgs.gotools @@ -40,6 +40,7 @@ pkgs.prettier pkgs.prettier-plugin-go-template proj.packages.${system}.default + pkgs.typescript pkgs.watchexec ]; }; diff --git a/html/template/sync/template-test.html b/html/template/sync/template-test.html index 3e59ab08..c1a01d5e 100644 --- a/html/template/sync/template-test.html +++ b/html/template/sync/template-test.html @@ -1,8 +1,18 @@ - + + - + + + Alpine + TypeScript Demo -

Hi Eli 2

+
+

+ +

Hello, !

+ +
+ + diff --git a/ts/main.ts b/ts/main.ts index df9c6173..85b60a1e 100644 --- a/ts/main.ts +++ b/ts/main.ts @@ -1,4 +1,19 @@ -// This will run when the page loads -window.addEventListener('DOMContentLoaded', () => { - console.log('Hello World'); -}); +import Alpine from './vendor/alpinejs-3.15.8.js'; + +interface GreetingComponent { + message: string; + name: string; + updateMessage(): void; +} + +Alpine.data('greeting', (): GreetingComponent => ({ + message: 'Welcome to Alpine + TypeScript!', + name: 'World', + + updateMessage() { + this.message = 'Message updated at ' + new Date().toLocaleTimeString(); + } +})); + +Alpine.start(); + diff --git a/ts/vendor/alpine-3.15.8.d.ts b/ts/vendor/alpine-3.15.8.d.ts new file mode 100644 index 00000000..83645f32 --- /dev/null +++ b/ts/vendor/alpine-3.15.8.d.ts @@ -0,0 +1 @@ +Couldn't find the requested file /packages/alpinejs/types/index.d.ts in alpinejs. \ No newline at end of file diff --git a/ts/vendor/alpinejs-3.15.8.js b/ts/vendor/alpinejs-3.15.8.js new file mode 100644 index 00000000..cb61931e --- /dev/null +++ b/ts/vendor/alpinejs-3.15.8.js @@ -0,0 +1,3748 @@ +// packages/alpinejs/src/scheduler.js +var flushPending = false; +var flushing = false; +var queue = []; +var lastFlushedIndex = -1; +function scheduler(callback) { + queueJob(callback); +} +function queueJob(job) { + if (!queue.includes(job)) queue.push(job); + queueFlush(); +} +function dequeueJob(job) { + let index = queue.indexOf(job); + if (index !== -1 && index > lastFlushedIndex) queue.splice(index, 1); +} +function queueFlush() { + if (!flushing && !flushPending) { + flushPending = true; + queueMicrotask(flushJobs); + } +} +function flushJobs() { + flushPending = false; + flushing = true; + for (let i = 0; i < queue.length; i++) { + queue[i](); + lastFlushedIndex = i; + } + queue.length = 0; + lastFlushedIndex = -1; + flushing = false; +} + +// packages/alpinejs/src/reactivity.js +var reactive; +var effect; +var release; +var raw; +var shouldSchedule = true; +function disableEffectScheduling(callback) { + shouldSchedule = false; + callback(); + shouldSchedule = true; +} +function setReactivityEngine(engine) { + reactive = engine.reactive; + release = engine.release; + effect = (callback) => + engine.effect(callback, { + scheduler: (task) => { + if (shouldSchedule) { + scheduler(task); + } else { + task(); + } + }, + }); + raw = engine.raw; +} +function overrideEffect(override) { + effect = override; +} +function elementBoundEffect(el) { + let cleanup2 = () => {}; + let wrappedEffect = (callback) => { + let effectReference = effect(callback); + if (!el._x_effects) { + el._x_effects = /* @__PURE__ */ new Set(); + el._x_runEffects = () => { + el._x_effects.forEach((i) => i()); + }; + } + el._x_effects.add(effectReference); + cleanup2 = () => { + if (effectReference === void 0) return; + el._x_effects.delete(effectReference); + release(effectReference); + }; + return effectReference; + }; + return [ + wrappedEffect, + () => { + cleanup2(); + }, + ]; +} +function watch(getter, callback) { + let firstTime = true; + let oldValue; + let effectReference = effect(() => { + let value = getter(); + JSON.stringify(value); + if (!firstTime) { + queueMicrotask(() => { + callback(value, oldValue); + oldValue = value; + }); + } else { + oldValue = value; + } + firstTime = false; + }); + return () => release(effectReference); +} + +// packages/alpinejs/src/utils/dispatch.js +function dispatch(el, name, detail = {}) { + el.dispatchEvent( + new CustomEvent(name, { + detail, + bubbles: true, + // Allows events to pass the shadow DOM barrier. + composed: true, + cancelable: true, + }), + ); +} + +// packages/alpinejs/src/utils/walk.js +function walk(el, callback) { + if (typeof ShadowRoot === "function" && el instanceof ShadowRoot) { + Array.from(el.children).forEach((el2) => walk(el2, callback)); + return; + } + let skip = false; + callback(el, () => (skip = true)); + if (skip) return; + let node = el.firstElementChild; + while (node) { + walk(node, callback, false); + node = node.nextElementSibling; + } +} + +// packages/alpinejs/src/utils/warn.js +function warn(message, ...args) { + console.warn(`Alpine Warning: ${message}`, ...args); +} + +// packages/alpinejs/src/lifecycle.js +var started = false; +function start() { + if (started) + warn( + "Alpine has already been initialized on this page. Calling Alpine.start() more than once can cause problems.", + ); + started = true; + if (!document.body) + warn( + "Unable to initialize. Trying to load Alpine before `` is available. Did you forget to add `defer` in Alpine's `