1tube 0.1.0 → 0.1.2
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/.env.example +1 -1
- package/README.md +6 -0
- package/package.json +2 -2
- package/src/discovery.ts +6 -1
- package/src/registry.ts +5 -0
- package/src/server.ts +59 -8
package/.env.example
CHANGED
package/README.md
CHANGED
|
@@ -23,6 +23,12 @@ bun run dev -- --functions ../sciobot-next/supabase/functions
|
|
|
23
23
|
|
|
24
24
|
The gateway starts on `http://localhost:3100`. Functions are available at `http://localhost:3100/functions/v1/<name>`.
|
|
25
25
|
|
|
26
|
+
In dev mode, 1tube also watches the functions directory and reloads handlers in-process on filesystem changes (including newly created function folders).
|
|
27
|
+
|
|
28
|
+
### Deno npm lifecycle scripts
|
|
29
|
+
|
|
30
|
+
Deno does not run npm `postinstall` / build scripts unless you allow them. `deno.lock` may still list transitive packages such as `protobufjs`; the `check` script uses `--allow-scripts=npm:protobufjs` so `bun run check` / `npm publish` (via `prepublishOnly`) stays warning-free. That script is only needed for dependency install — **1tube’s runtime graph is just Hono + JSR std**.
|
|
31
|
+
|
|
26
32
|
## Endpoints
|
|
27
33
|
|
|
28
34
|
| Path | Description |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "1tube",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Self-hosted Supabase Edge Functions gateway for Deno, plus an ESLint plugin for consumers",
|
|
6
6
|
"license": "MIT",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"dev": "deno task dev",
|
|
34
34
|
"serve": "deno task serve",
|
|
35
35
|
"typecheck": "deno check src/server.ts eslint-plugin.js",
|
|
36
|
-
"check": "deno cache src/server.ts",
|
|
36
|
+
"check": "deno cache --allow-scripts=npm:protobufjs src/server.ts",
|
|
37
37
|
"prepublishOnly": "bun run typecheck && bun run check"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
package/src/discovery.ts
CHANGED
|
@@ -13,6 +13,7 @@ import type { FunctionRegistry } from "./registry.ts";
|
|
|
13
13
|
export async function discoverAndLoad(
|
|
14
14
|
functionsDir: string,
|
|
15
15
|
registry: FunctionRegistry,
|
|
16
|
+
options?: { cacheBust?: string },
|
|
16
17
|
): Promise<{ loaded: string[]; skipped: string[]; errors: Array<{ name: string; error: string }> }> {
|
|
17
18
|
const loaded: string[] = [];
|
|
18
19
|
const skipped: string[] = [];
|
|
@@ -45,7 +46,11 @@ export async function discoverAndLoad(
|
|
|
45
46
|
registry.setCurrentFunction(name);
|
|
46
47
|
|
|
47
48
|
try {
|
|
48
|
-
|
|
49
|
+
const moduleUrl = toFileUrl(indexPath);
|
|
50
|
+
if (options?.cacheBust) {
|
|
51
|
+
moduleUrl.searchParams.set("v", options.cacheBust);
|
|
52
|
+
}
|
|
53
|
+
await import(moduleUrl.href);
|
|
49
54
|
loaded.push(name);
|
|
50
55
|
} catch (err) {
|
|
51
56
|
const msg = err instanceof Error ? err.message : String(err);
|
package/src/registry.ts
CHANGED
package/src/server.ts
CHANGED
|
@@ -77,20 +77,71 @@ applyLocalDefaults();
|
|
|
77
77
|
const registry = new FunctionRegistry();
|
|
78
78
|
(globalThis as any).__edgeFunctionRegistry = registry;
|
|
79
79
|
|
|
80
|
+
async function reloadFunctions(reason: string) {
|
|
81
|
+
console.log(`[1tube] Reloading functions (${reason})...`);
|
|
82
|
+
registry.clear();
|
|
83
|
+
const cacheBust = `${Date.now()}-${crypto.randomUUID()}`;
|
|
84
|
+
const { loaded, skipped, errors } = await discoverAndLoad(functionsPath, registry, { cacheBust });
|
|
85
|
+
|
|
86
|
+
console.log(`[1tube] Loaded ${loaded.length} functions, skipped ${skipped.length} directories`);
|
|
87
|
+
if (loaded.length > 0) {
|
|
88
|
+
console.log(`[1tube] Functions: ${loaded.join(", ")}`);
|
|
89
|
+
}
|
|
90
|
+
if (errors.length > 0) {
|
|
91
|
+
console.error(`[1tube] ${errors.length} function(s) failed to load (check .env for missing vars):`);
|
|
92
|
+
for (const e of errors) {
|
|
93
|
+
console.error(` ${e.name}: ${e.error}`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
80
98
|
console.log(`[1tube] Loading functions from: ${functionsPath}`);
|
|
81
|
-
|
|
99
|
+
await reloadFunctions("initial boot");
|
|
100
|
+
|
|
101
|
+
let reloadTimer: number | undefined;
|
|
102
|
+
let isReloading = false;
|
|
103
|
+
let needsAnotherReload = false;
|
|
82
104
|
|
|
83
|
-
|
|
84
|
-
if (
|
|
85
|
-
|
|
105
|
+
function scheduleReload(reason: string) {
|
|
106
|
+
if (reloadTimer !== undefined) {
|
|
107
|
+
clearTimeout(reloadTimer);
|
|
108
|
+
}
|
|
109
|
+
reloadTimer = setTimeout(async () => {
|
|
110
|
+
if (isReloading) {
|
|
111
|
+
needsAnotherReload = true;
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
isReloading = true;
|
|
116
|
+
try {
|
|
117
|
+
await reloadFunctions(reason);
|
|
118
|
+
} catch (err) {
|
|
119
|
+
console.error("[1tube] Reload failed:", err);
|
|
120
|
+
} finally {
|
|
121
|
+
isReloading = false;
|
|
122
|
+
if (needsAnotherReload) {
|
|
123
|
+
needsAnotherReload = false;
|
|
124
|
+
scheduleReload("batched filesystem updates");
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}, 200);
|
|
86
128
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
129
|
+
|
|
130
|
+
async function watchFunctions() {
|
|
131
|
+
try {
|
|
132
|
+
const watcher = Deno.watchFs(functionsPath, { recursive: true });
|
|
133
|
+
console.log(`[1tube] HMR watching: ${functionsPath}`);
|
|
134
|
+
for await (const event of watcher) {
|
|
135
|
+
if (event.paths.length === 0) continue;
|
|
136
|
+
scheduleReload(`${event.kind} (${event.paths.length} path(s))`);
|
|
137
|
+
}
|
|
138
|
+
} catch (err) {
|
|
139
|
+
console.warn("[1tube] HMR watcher disabled:", err);
|
|
91
140
|
}
|
|
92
141
|
}
|
|
93
142
|
|
|
143
|
+
watchFunctions();
|
|
144
|
+
|
|
94
145
|
// ---------------------------------------------------------------------------
|
|
95
146
|
// HTTP Server
|
|
96
147
|
// ---------------------------------------------------------------------------
|