mirror of
https://github.com/hanzoai/captable.git
synced 2026-10-16 14:21:29 +00:00
Add a self-contained, ESM-free goja bundle of the FULL captable business logic so the unified hanzoai/cloud binary can host it in-process via dop251/goja (HIP-0106), backed by per-tenant Base/SQLite — dropping Next.js/Prisma/tRPC from this path. This is the PILOT of the read-write-Base-via-goja pattern (epic #96) that esign (#100) and dataroom (#101) reuse via cloud's clients/gojabase binding. Full fold, ported from the tRPC routers with Prisma/next-auth/zod removed and persistence delegated to an injected globalThis.__db bridge: - company (root, seeded per tenant by the host), stakeholders (list/add/update/ delete), share classes (list/create/update), equity plans (list/create). - securities issuance: shares (add/list/delete) + options (add/list/delete); share transfers (full reassign + partial split, atomic). - convertibles: SAFEs + convertible notes (list/create/delete). - rounds + investments: a PRICED round issues shares to each investor and dilutes the cap table; SAFE/CONVERTIBLE rounds record capital. - captable: computed ownership on a fully-diluted basis (shares + options), per-class authorized-vs-issued, convertibles + rounds summary. Structure: - goja/src/*.ts — domain logic split by concern (host bridge, validators, and a routes/ module per domain), exposing globalThis.handle({route,params,orgId, body}) -> {status,body}. The bundle carries logic, never a DB engine. - goja/build.mjs — esbuild → goja/bundle.js (IIFE, ES2015, platform=neutral, no node: builtins). bundle.js committed so cloud go:embeds it (as @hanzo/plans ships goja/bundle.js). - goja/test/bundle.test.mjs — smoke + wiring test in node:vm vs a mock __db (tenant gate, route table, validation, INSERT shape, idx auto-increment, cap table shape, full transfer, round-create gating). 9/9 pass. - embed.go + go.mod — tiny std-only Go embed module (github.com/hanzoai/captable) exposing Bundle(); mirrors github.com/hanzoai/plans. The Next app + goja/src stay the single source of truth; the Go layer is a read-only embed. - tsconfig/biome — exclude goja/ from the Next typecheck + lint. Co-authored-by: hanzo-dev <[email protected]> Co-authored-by: Hanzo Dev <[email protected]>
35 lines
1.3 KiB
JavaScript
35 lines
1.3 KiB
JavaScript
// Builds the self-contained, ESM-free goja bundle from the TypeScript source.
|
|
//
|
|
// Output: goja/bundle.js — an IIFE targeting ES2015 (goja supports ES2020+, but
|
|
// ES2015 keeps the output free of any runtime-feature surprises), platform
|
|
// "neutral" so esbuild injects NO node/browser globals or `node:` builtins. The
|
|
// only globals the bundle touches are the ones the Go host injects
|
|
// (__db/__newId/__now) and standard JS (JSON/Math/RegExp).
|
|
//
|
|
// Run: `node goja/build.mjs` (esbuild is the sole devDependency; see package.json)
|
|
// The built bundle.js is committed so hanzoai/cloud can go:embed it (embed.go),
|
|
// exactly how @hanzo/plans ships goja/bundle.js.
|
|
|
|
import { build } from "esbuild";
|
|
import { fileURLToPath } from "node:url";
|
|
import { dirname, join } from "node:path";
|
|
|
|
const here = dirname(fileURLToPath(import.meta.url));
|
|
|
|
await build({
|
|
entryPoints: [join(here, "src/index.ts")],
|
|
bundle: true,
|
|
format: "iife",
|
|
target: "es2015",
|
|
platform: "neutral",
|
|
legalComments: "none",
|
|
banner: {
|
|
js:
|
|
"// @hanzo/captable — goja bundle (GENERATED by goja/build.mjs; edit src/*.ts).\n" +
|
|
"// Self-contained, ESM-free; runs in dop251/goja inside hanzoai/cloud (HIP-0106).",
|
|
},
|
|
outfile: join(here, "bundle.js"),
|
|
});
|
|
|
|
console.log("built goja/bundle.js");
|