@edge-base/server 0.1.3 → 0.1.4

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.
Files changed (66) hide show
  1. package/admin-build/_app/immutable/chunks/{DskOoVLT.js → 6a5nHrK1.js} +1 -1
  2. package/admin-build/_app/immutable/chunks/{DroeC-Do.js → B-bKFoyc.js} +1 -1
  3. package/admin-build/_app/immutable/chunks/{D8o7yzcA.js → BebaNaL1.js} +1 -1
  4. package/admin-build/_app/immutable/chunks/{CnWwy2Sf.js → Bed8WcZp.js} +1 -1
  5. package/admin-build/_app/immutable/chunks/{CF95mcQY.js → Bwq290TU.js} +1 -1
  6. package/admin-build/_app/immutable/chunks/{v2HHbTgy.js → CfT4rpr6.js} +1 -1
  7. package/admin-build/_app/immutable/chunks/{BwxFS5FL.js → ChX-qyfY.js} +1 -1
  8. package/admin-build/_app/immutable/chunks/{I0AZRbV2.js → DMIs26Al.js} +1 -1
  9. package/admin-build/_app/immutable/chunks/DSsNi9zA.js +1 -0
  10. package/admin-build/_app/immutable/chunks/{MKsm6wXE.js → DYRfe1lC.js} +1 -1
  11. package/admin-build/_app/immutable/chunks/{DTmaM1M6.js → DuldBlfT.js} +1 -1
  12. package/admin-build/_app/immutable/chunks/{BOSBsYO8.js → FA-xxanK.js} +1 -1
  13. package/admin-build/_app/immutable/chunks/{9Ch6RgcX.js → Fw9oK_yh.js} +1 -1
  14. package/admin-build/_app/immutable/chunks/eLBKp9m8.js +1 -0
  15. package/admin-build/_app/immutable/chunks/{BvukSxhJ.js → mVKEd0n6.js} +3 -3
  16. package/admin-build/_app/immutable/chunks/{CBVE2cdU.js → mmI0365x.js} +1 -1
  17. package/admin-build/_app/immutable/entry/{app.Dh4eYd90.js → app.B0Wfop7v.js} +2 -2
  18. package/admin-build/_app/immutable/entry/start.C1a0bzUm.js +1 -0
  19. package/admin-build/_app/immutable/nodes/{0._kCczuod.js → 0.DXd3Dmjw.js} +1 -1
  20. package/admin-build/_app/immutable/nodes/{1.C8vaAzdV.js → 1.DYs0DOEf.js} +1 -1
  21. package/admin-build/_app/immutable/nodes/{10.TsbpWcyB.js → 10.C5zdvzz2.js} +1 -1
  22. package/admin-build/_app/immutable/nodes/{11.DbwjQWdP.js → 11.CZn94rTD.js} +1 -1
  23. package/admin-build/_app/immutable/nodes/{12.BMCb3LcM.js → 12.zeHwsLsn.js} +1 -1
  24. package/admin-build/_app/immutable/nodes/{13.CTXx-p7a.js → 13.nkWGiViq.js} +1 -1
  25. package/admin-build/_app/immutable/nodes/{14.BW1Sfg3E.js → 14.C0cOviHd.js} +1 -1
  26. package/admin-build/_app/immutable/nodes/{15.DAKEfLVF.js → 15.q5eTZ0ns.js} +1 -1
  27. package/admin-build/_app/immutable/nodes/{16.BZHOIVRq.js → 16.BrpfTEYF.js} +1 -1
  28. package/admin-build/_app/immutable/nodes/{17.DcntvsXi.js → 17.3p6MQums.js} +1 -1
  29. package/admin-build/_app/immutable/nodes/{18.Badw-bZ2.js → 18.aj9cF39Y.js} +1 -1
  30. package/admin-build/_app/immutable/nodes/{19.BZHOIVRq.js → 19.BrpfTEYF.js} +1 -1
  31. package/admin-build/_app/immutable/nodes/{20.DDTfgFOS.js → 20.BUEsrK6V.js} +1 -1
  32. package/admin-build/_app/immutable/nodes/21.Bch9bUk6.js +1 -0
  33. package/admin-build/_app/immutable/nodes/{22.DLaL76VE.js → 22.V2clGNAS.js} +1 -1
  34. package/admin-build/_app/immutable/nodes/{23.D1tjWuvB.js → 23.3XSLKKOr.js} +1 -1
  35. package/admin-build/_app/immutable/nodes/{24.8cwANb8Q.js → 24.F-qrYmNi.js} +1 -1
  36. package/admin-build/_app/immutable/nodes/{25.DCU-ztvR.js → 25.BdrY4DyK.js} +1 -1
  37. package/admin-build/_app/immutable/nodes/{26.CuHUfaEI.js → 26.D0WXHf08.js} +1 -1
  38. package/admin-build/_app/immutable/nodes/{27.fOpy2ckO.js → 27.DvWhuH9-.js} +1 -1
  39. package/admin-build/_app/immutable/nodes/{28.DWB877rH.js → 28.5Oz_jlro.js} +1 -1
  40. package/admin-build/_app/immutable/nodes/{29.D9hvrxFP.js → 29.dDyAUaup.js} +1 -1
  41. package/admin-build/_app/immutable/nodes/{3.BJG5UaW0.js → 3.BcXkDIYV.js} +1 -1
  42. package/admin-build/_app/immutable/nodes/{30.52Okvb4S.js → 30.2JCWdjTn.js} +1 -1
  43. package/admin-build/_app/immutable/nodes/{31.B2rKWEXY.js → 31.qG9kkJ9Q.js} +1 -1
  44. package/admin-build/_app/immutable/nodes/{4.BMrPKdZ6.js → 4.Cl5grO75.js} +1 -1
  45. package/admin-build/_app/immutable/nodes/{5.BHBRNfgt.js → 5.Bel35v4W.js} +1 -1
  46. package/admin-build/_app/immutable/nodes/{6.Uq3G0mmd.js → 6.CjpfkMIg.js} +1 -1
  47. package/admin-build/_app/immutable/nodes/{7.BS-ss8zw.js → 7.CA1OBWip.js} +1 -1
  48. package/admin-build/_app/immutable/nodes/{8.5bzwkzMM.js → 8.DS5xal_X.js} +1 -1
  49. package/admin-build/_app/immutable/nodes/{9.BA61CCFG.js → 9.OYw1MaR9.js} +1 -1
  50. package/admin-build/_app/version.json +1 -1
  51. package/admin-build/index.html +7 -7
  52. package/package.json +3 -3
  53. package/src/__tests__/rate-limit.test.ts +4 -3
  54. package/src/__tests__/websocket-pending.test.ts +4 -4
  55. package/src/durable-objects/database-do.ts +8 -3
  56. package/src/lib/do-router.ts +8 -0
  57. package/src/lib/functions.ts +23 -1
  58. package/src/middleware/auth.ts +9 -0
  59. package/src/middleware/rate-limit.ts +25 -3
  60. package/src/routes/database-live.ts +1 -1
  61. package/src/routes/functions.ts +9 -1
  62. package/src/routes/vectorize.ts +4 -4
  63. package/admin-build/_app/immutable/chunks/B-pVQkKM.js +0 -1
  64. package/admin-build/_app/immutable/chunks/WtDa8jKW.js +0 -1
  65. package/admin-build/_app/immutable/entry/start.DjnjDre4.js +0 -1
  66. package/admin-build/_app/immutable/nodes/21.BbdBT511.js +0 -1
@@ -1 +1 @@
1
- import"../chunks/CWj6FrbW.js";import{o as U}from"../chunks/Bn2NtlTj.js";import{p as j,a as z,f as G,c as b,g as t,s as m,r as g,u as n,b as y,d as D,t as J}from"../chunks/BdTBlfLy.js";import{d as K,s as N,a as O}from"../chunks/DtZk82gG.js";import{a as Q,t as V,e as W,i as X}from"../chunks/MKsm6wXE.js";import{a as F,f as I}from"../chunks/DEELgv7K.js";import{s as Y}from"../chunks/CoI6jjbg.js";import{P as Z}from"../chunks/B8s_s9QY.js";import{a as tt}from"../chunks/Q2nPFxS6.js";import{M as _,T as et}from"../chunks/CnWwy2Sf.js";import{D as at,T as rt}from"../chunks/DroeC-Do.js";var nt=I("<button> </button>"),st=I('<div class="range-selector"></div>'),ot=I('<div class="analytics-grid"><!> <!> <!> <!></div> <div class="analytics-chart"><!></div> <div class="analytics-bottom"><!> <!></div>',1);function bt(w,M){j(M,!0);let s=D(!0),o=D(null),p=D("24h");const T=[{value:"1h",label:"1H"},{value:"6h",label:"6H"},{value:"24h",label:"24H"},{value:"7d",label:"7D"},{value:"30d",label:"30D"}],k=n(()=>()=>{switch(t(p)){case"1h":return"minute";case"6h":case"24h":return"hour";default:return"day"}});async function $(){try{const e=await Q.fetch(`data/analytics?range=${t(p)}&category=function&metric=overview&groupBy=${t(k)()}`);y(o,e,!0)}catch(e){V(e instanceof Error?e.message:"Failed to load functions analytics")}finally{y(s,!1)}}function A(e){y(p,e,!0),y(s,!0),$()}U(()=>{$();const e=setInterval($,3e4);return()=>clearInterval(e)});const H=n(()=>()=>{var c;if(!((c=t(o))!=null&&c.summary))return 0;const{totalRequests:e,totalErrors:a}=t(o).summary;return e>0?a/e*100:0}),B=n(()=>()=>{var e;return(((e=t(o))==null?void 0:e.timeSeries)||[]).map(a=>({timestamp:a.timestamp,value:a.requests??a.value??0}))}),C=n(()=>()=>{var e;return(((e=t(o))==null?void 0:e.breakdown)||[]).map(a=>({label:a.label||"other",value:a.count}))}),E=n(()=>()=>{var e;return(((e=t(o))==null?void 0:e.topItems)||[]).map(a=>({label:a.label,count:a.count,secondary:`${Math.round(a.avgLatency)}ms · ${a.errorRate.toFixed(1)}% 5xx`}))});Z(w,{title:"Functions Analytics",description:"Serverless function execution and performance metrics",get docsHref(){return tt},actions:a=>{var c=st();W(c,21,()=>T,X,(f,d)=>{var l=nt();let v;var h=b(l,!0);g(l),J(()=>{v=Y(l,1,"range-btn",null,v,{"range-btn--active":t(p)===t(d).value}),N(h,t(d).label)}),O("click",l,()=>A(t(d).value)),F(f,l)}),g(c),F(a,c)},children:(a,c)=>{var f=ot(),d=G(f),l=b(d);{let r=n(()=>{var i,u;return((u=(i=t(o))==null?void 0:i.summary)==null?void 0:u.totalRequests)??0});_(l,{label:"Invocations",get value(){return t(r)},get loading(){return t(s)}})}var v=m(l,2);{let r=n(()=>{var i,u;return((u=(i=t(o))==null?void 0:i.summary)==null?void 0:u.uniqueUsers)??0});_(v,{label:"Unique Users",get value(){return t(r)},get loading(){return t(s)}})}var h=m(v,2);{let r=n(()=>t(H)().toFixed(1));_(h,{label:"5xx Rate",get value(){return t(r)},unit:"%",get loading(){return t(s)}})}var L=m(h,2);{let r=n(()=>{var i,u;return Math.round(((u=(i=t(o))==null?void 0:i.summary)==null?void 0:u.avgLatency)??0)});_(L,{label:"Avg Duration",get value(){return t(r)},unit:"ms",get loading(){return t(s)}})}g(d);var x=m(d,2),P=b(x);{let r=n(()=>t(B)());et(P,{get data(){return t(r)},type:"bar",height:240,label:"Function invocations over time",get loading(){return t(s)},color:"#dc2626"})}g(x);var R=m(x,2),q=b(R);{let r=n(()=>t(C)());at(q,{get items(){return t(r)},title:"Functions by invocation count",get loading(){return t(s)}})}var S=m(q,2);{let r=n(()=>t(E)());rt(S,{get items(){return t(r)},title:"Top Functions",get loading(){return t(s)}})}g(R),F(a,f)}}),z()}K(["click"]);export{bt as component};
1
+ import"../chunks/CWj6FrbW.js";import{o as U}from"../chunks/Bn2NtlTj.js";import{p as j,a as z,f as G,c as b,g as t,s as m,r as g,u as n,b as y,d as D,t as J}from"../chunks/BdTBlfLy.js";import{d as K,s as N,a as O}from"../chunks/DtZk82gG.js";import{a as Q,t as V,e as W,i as X}from"../chunks/DYRfe1lC.js";import{a as F,f as I}from"../chunks/DEELgv7K.js";import{s as Y}from"../chunks/CoI6jjbg.js";import{P as Z}from"../chunks/B8s_s9QY.js";import{a as tt}from"../chunks/Q2nPFxS6.js";import{M as _,T as et}from"../chunks/Bed8WcZp.js";import{D as at,T as rt}from"../chunks/B-bKFoyc.js";var nt=I("<button> </button>"),st=I('<div class="range-selector"></div>'),ot=I('<div class="analytics-grid"><!> <!> <!> <!></div> <div class="analytics-chart"><!></div> <div class="analytics-bottom"><!> <!></div>',1);function bt(w,M){j(M,!0);let s=D(!0),o=D(null),p=D("24h");const T=[{value:"1h",label:"1H"},{value:"6h",label:"6H"},{value:"24h",label:"24H"},{value:"7d",label:"7D"},{value:"30d",label:"30D"}],k=n(()=>()=>{switch(t(p)){case"1h":return"minute";case"6h":case"24h":return"hour";default:return"day"}});async function $(){try{const e=await Q.fetch(`data/analytics?range=${t(p)}&category=function&metric=overview&groupBy=${t(k)()}`);y(o,e,!0)}catch(e){V(e instanceof Error?e.message:"Failed to load functions analytics")}finally{y(s,!1)}}function A(e){y(p,e,!0),y(s,!0),$()}U(()=>{$();const e=setInterval($,3e4);return()=>clearInterval(e)});const H=n(()=>()=>{var c;if(!((c=t(o))!=null&&c.summary))return 0;const{totalRequests:e,totalErrors:a}=t(o).summary;return e>0?a/e*100:0}),B=n(()=>()=>{var e;return(((e=t(o))==null?void 0:e.timeSeries)||[]).map(a=>({timestamp:a.timestamp,value:a.requests??a.value??0}))}),C=n(()=>()=>{var e;return(((e=t(o))==null?void 0:e.breakdown)||[]).map(a=>({label:a.label||"other",value:a.count}))}),E=n(()=>()=>{var e;return(((e=t(o))==null?void 0:e.topItems)||[]).map(a=>({label:a.label,count:a.count,secondary:`${Math.round(a.avgLatency)}ms · ${a.errorRate.toFixed(1)}% 5xx`}))});Z(w,{title:"Functions Analytics",description:"Serverless function execution and performance metrics",get docsHref(){return tt},actions:a=>{var c=st();W(c,21,()=>T,X,(f,d)=>{var l=nt();let v;var h=b(l,!0);g(l),J(()=>{v=Y(l,1,"range-btn",null,v,{"range-btn--active":t(p)===t(d).value}),N(h,t(d).label)}),O("click",l,()=>A(t(d).value)),F(f,l)}),g(c),F(a,c)},children:(a,c)=>{var f=ot(),d=G(f),l=b(d);{let r=n(()=>{var i,u;return((u=(i=t(o))==null?void 0:i.summary)==null?void 0:u.totalRequests)??0});_(l,{label:"Invocations",get value(){return t(r)},get loading(){return t(s)}})}var v=m(l,2);{let r=n(()=>{var i,u;return((u=(i=t(o))==null?void 0:i.summary)==null?void 0:u.uniqueUsers)??0});_(v,{label:"Unique Users",get value(){return t(r)},get loading(){return t(s)}})}var h=m(v,2);{let r=n(()=>t(H)().toFixed(1));_(h,{label:"5xx Rate",get value(){return t(r)},unit:"%",get loading(){return t(s)}})}var L=m(h,2);{let r=n(()=>{var i,u;return Math.round(((u=(i=t(o))==null?void 0:i.summary)==null?void 0:u.avgLatency)??0)});_(L,{label:"Avg Duration",get value(){return t(r)},unit:"ms",get loading(){return t(s)}})}g(d);var x=m(d,2),P=b(x);{let r=n(()=>t(B)());et(P,{get data(){return t(r)},type:"bar",height:240,label:"Function invocations over time",get loading(){return t(s)},color:"#dc2626"})}g(x);var R=m(x,2),q=b(R);{let r=n(()=>t(C)());at(q,{get items(){return t(r)},title:"Functions by invocation count",get loading(){return t(s)}})}var S=m(q,2);{let r=n(()=>t(E)());rt(S,{get items(){return t(r)},title:"Top Functions",get loading(){return t(s)}})}g(R),F(a,f)}}),z()}K(["click"]);export{bt as component};
@@ -1 +1 @@
1
- {"version":"1773877838042"}
1
+ {"version":"1773964688040"}
@@ -5,12 +5,12 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1" />
6
6
  <title>EdgeBase Admin</title>
7
7
  <link rel="icon" href="/admin/favicon.svg" type="image/svg+xml" />
8
- <link href="/admin/_app/immutable/entry/start.DjnjDre4.js" rel="modulepreload">
9
- <link href="/admin/_app/immutable/chunks/WtDa8jKW.js" rel="modulepreload">
8
+ <link href="/admin/_app/immutable/entry/start.C1a0bzUm.js" rel="modulepreload">
9
+ <link href="/admin/_app/immutable/chunks/eLBKp9m8.js" rel="modulepreload">
10
10
  <link href="/admin/_app/immutable/chunks/BdTBlfLy.js" rel="modulepreload">
11
11
  <link href="/admin/_app/immutable/chunks/Bn2NtlTj.js" rel="modulepreload">
12
- <link href="/admin/_app/immutable/chunks/B-pVQkKM.js" rel="modulepreload">
13
- <link href="/admin/_app/immutable/entry/app.Dh4eYd90.js" rel="modulepreload">
12
+ <link href="/admin/_app/immutable/chunks/DSsNi9zA.js" rel="modulepreload">
13
+ <link href="/admin/_app/immutable/entry/app.B0Wfop7v.js" rel="modulepreload">
14
14
  <link href="/admin/_app/immutable/chunks/B2bEC_Hm.js" rel="modulepreload">
15
15
  <link href="/admin/_app/immutable/chunks/Bb0e0sAP.js" rel="modulepreload">
16
16
  <link href="/admin/_app/immutable/chunks/DtZk82gG.js" rel="modulepreload">
@@ -26,7 +26,7 @@
26
26
  <div style="display: contents">
27
27
  <script>
28
28
  {
29
- __sveltekit_1f6v8l6 = {
29
+ __sveltekit_v590bi = {
30
30
  base: "/admin",
31
31
  assets: "/admin"
32
32
  };
@@ -34,8 +34,8 @@
34
34
  const element = document.currentScript.parentElement;
35
35
 
36
36
  Promise.all([
37
- import("/admin/_app/immutable/entry/start.DjnjDre4.js"),
38
- import("/admin/_app/immutable/entry/app.Dh4eYd90.js")
37
+ import("/admin/_app/immutable/entry/start.C1a0bzUm.js"),
38
+ import("/admin/_app/immutable/entry/app.B0Wfop7v.js")
39
39
  ]).then(([kit, app]) => {
40
40
  kit.start(app, element);
41
41
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@edge-base/server",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "description": "EdgeBase runtime assets consumed by the EdgeBase CLI",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -8,7 +8,7 @@
8
8
  "url": "https://github.com/edge-base/edgebase.git",
9
9
  "directory": "packages/server"
10
10
  },
11
- "homepage": "https://edgebase.fun",
11
+ "homepage": "https://github.com/edge-base/edgebase/tree/main/packages/server",
12
12
  "bugs": "https://github.com/edge-base/edgebase/issues",
13
13
  "keywords": [
14
14
  "edgebase",
@@ -34,7 +34,7 @@
34
34
  "jose": "^6.0.0",
35
35
  "pg": "^8.16.3",
36
36
  "zod": "^4.3.6",
37
- "@edge-base/shared": "0.1.3"
37
+ "@edge-base/shared": "0.1.4"
38
38
  },
39
39
  "devDependencies": {
40
40
  "@cloudflare/vitest-pool-workers": "^0.8.71",
@@ -12,6 +12,7 @@ import {
12
12
  parseWindow,
13
13
  FixedWindowCounter,
14
14
  RATE_LIMIT_DEFAULTS,
15
+ RATE_LIMIT_DEV_DEFAULTS,
15
16
  rateLimitMiddleware,
16
17
  } from '../middleware/rate-limit.js';
17
18
  import type { EdgeBaseConfig } from '@edge-base/shared';
@@ -44,13 +45,13 @@ describe('parseWindow', () => {
44
45
  describe('getLimit', () => {
45
46
  it('returns defaults when config is undefined', () => {
46
47
  const result = getLimit(undefined, 'db');
47
- expect(result).toEqual(RATE_LIMIT_DEFAULTS['db']);
48
+ expect(result).toEqual(RATE_LIMIT_DEV_DEFAULTS['db']);
48
49
  });
49
50
 
50
51
  it('returns defaults when rateLimiting is not set', () => {
51
52
  const config = {} as EdgeBaseConfig;
52
53
  const result = getLimit(config, 'db');
53
- expect(result).toEqual(RATE_LIMIT_DEFAULTS['db']);
54
+ expect(result).toEqual(RATE_LIMIT_DEV_DEFAULTS['db']);
54
55
  });
55
56
 
56
57
  it('returns defaults for unknown group', () => {
@@ -84,7 +85,7 @@ describe('getLimit', () => {
84
85
  db: undefined,
85
86
  },
86
87
  } as EdgeBaseConfig;
87
- expect(getLimit(config, 'db')).toEqual(RATE_LIMIT_DEFAULTS['db']);
88
+ expect(getLimit(config, 'db')).toEqual(RATE_LIMIT_DEV_DEFAULTS['db']);
88
89
  });
89
90
  });
90
91
 
@@ -146,9 +146,9 @@ describe('websocket pending helper functions', () => {
146
146
  it('acquires slots until the max pending threshold is reached', async () => {
147
147
  const kv = createMockKV();
148
148
 
149
- await expect(acquirePendingWebSocketSlot(kv, 'ws:pending:127.0.0.1', 2, 30)).resolves.toBe(true);
150
- await expect(acquirePendingWebSocketSlot(kv, 'ws:pending:127.0.0.1', 2, 30)).resolves.toBe(true);
151
- await expect(acquirePendingWebSocketSlot(kv, 'ws:pending:127.0.0.1', 2, 30)).resolves.toBe(false);
149
+ await expect(acquirePendingWebSocketSlot(kv, 'ws:pending:127.0.0.1', 2, 60)).resolves.toBe(true);
150
+ await expect(acquirePendingWebSocketSlot(kv, 'ws:pending:127.0.0.1', 2, 60)).resolves.toBe(true);
151
+ await expect(acquirePendingWebSocketSlot(kv, 'ws:pending:127.0.0.1', 2, 60)).resolves.toBe(false);
152
152
  expect(kv._store.data['ws:pending:127.0.0.1']?.value).toBe('2');
153
153
  });
154
154
 
@@ -156,7 +156,7 @@ describe('websocket pending helper functions', () => {
156
156
  const kv = createMockKV();
157
157
  kv._store.data['ws:pending:127.0.0.1'] = { value: '1' };
158
158
 
159
- await releasePendingWebSocketSlot(kv, 'ws:pending:127.0.0.1', 30);
159
+ await releasePendingWebSocketSlot(kv, 'ws:pending:127.0.0.1', 60);
160
160
 
161
161
  expect(kv._store.data['ws:pending:127.0.0.1']).toBeUndefined();
162
162
  });
@@ -2136,14 +2136,19 @@ export class DatabaseDO extends DurableObject<DOEnv> {
2136
2136
  return null;
2137
2137
  }
2138
2138
 
2139
- /** Ensure a table exists in this DO (throw if not). */
2139
+ /** Ensure a table exists in this DO, lazily creating it from config if needed. */
2140
2140
  private ensureTableExists(name: string): void {
2141
- // We rely on the schema init having already created the table
2142
2141
  const tables = [
2143
2142
  ...this.sql(`SELECT name FROM sqlite_master WHERE type = 'table' AND name = ?`, name),
2144
2143
  ];
2145
2144
  if (tables.length === 0) {
2146
- throw notFoundError(`Table "${name}" not found in this DO.`);
2145
+ // Table doesn't exist yet try to create it lazily from config
2146
+ const config = this.getTableConfig(name);
2147
+ if (config) {
2148
+ this.initTable(name, config);
2149
+ } else {
2150
+ throw notFoundError(`Table "${name}" not found in this DO.`);
2151
+ }
2147
2152
  }
2148
2153
  }
2149
2154
 
@@ -9,6 +9,7 @@
9
9
  * Constraint: `id` must NOT contain `:` character.
10
10
  */
11
11
  import { materializeConfig, type EdgeBaseConfig } from '@edge-base/shared';
12
+ import { counter } from '../middleware/rate-limit.js';
12
13
 
13
14
  const RUNTIME_CONFIG_GLOBAL_KEY = '__EDGEBASE_RUNTIME_CONFIG__';
14
15
 
@@ -145,11 +146,18 @@ function readGlobalRuntimeConfig(): EdgeBaseConfig | null {
145
146
  */
146
147
  export function setConfig(config: EdgeBaseConfig): void {
147
148
  const normalized = materializeConfig(config);
149
+ const configChanged = _runtimeConfig !== null;
148
150
  _runtimeConfig = normalized;
149
151
 
150
152
  if (typeof globalThis === 'object' && globalThis !== null) {
151
153
  (globalThis as Record<string, unknown>)[RUNTIME_CONFIG_GLOBAL_KEY] = normalized;
152
154
  }
155
+
156
+ // Reset rate limit counters when config changes (e.g. hot-reload in dev)
157
+ // to avoid stale counters blocking requests under new limits.
158
+ if (configChanged) {
159
+ counter.reset();
160
+ }
153
161
  }
154
162
 
155
163
  /**
@@ -285,6 +285,17 @@ export interface FunctionVectorizeProxy {
285
285
  export interface FunctionContext {
286
286
  request: Request;
287
287
  auth: AuthContext | null;
288
+ /**
289
+ * Convenience shortcut to `admin.db()`.
290
+ * Access database tables directly without going through `admin`.
291
+ *
292
+ * @example
293
+ * // Static DB
294
+ * await context.db('shared').table('posts').list()
295
+ * // Dynamic DB
296
+ * await context.db('workspace', 'ws-456').table('documents').list()
297
+ */
298
+ db: FunctionAdminContext['db'];
288
299
  /**
289
300
  * Server-side EdgeBase admin client (§5,).
290
301
  * Use context.admin.db(namespace, id?).table(name) for all DB access.
@@ -353,6 +364,16 @@ function getRegistryName(key: string, def: FunctionDefinition): string {
353
364
  }
354
365
 
355
366
  export function registerFunction(name: string, def: FunctionDefinition): void {
367
+ if (!def || typeof def !== 'object' || !def.trigger) {
368
+ const received = typeof def === 'function'
369
+ ? 'a plain function'
370
+ : `${typeof def} (${JSON.stringify(def)?.slice(0, 100)})`;
371
+ throw new Error(
372
+ `registerFunction('${name}'): expected a FunctionDefinition with a 'trigger' property, but received ${received}. ` +
373
+ `Functions must use defineFunction() from '@edge-base/shared' and be exported as named HTTP method exports ` +
374
+ `(e.g. export const GET = defineFunction(...)). See https://docs.edgebase.dev/functions for details.`,
375
+ );
376
+ }
356
377
  functionRegistry.set(buildRegistryKey(name, def), def);
357
378
  }
358
379
 
@@ -655,7 +676,7 @@ export function wrapMethodExport(
655
676
  if (typeof handler === 'function') {
656
677
  fn = handler;
657
678
  } else if (handler && typeof handler === 'object') {
658
- fn = handler.handler ?? (handler as unknown as (ctx: unknown) => Promise<unknown>);
679
+ fn = (handler.handler ?? handler) as unknown as (ctx: unknown) => Promise<unknown>;
659
680
  captcha = handler.captcha;
660
681
  if ('trigger' in handler && handler.trigger && typeof handler.trigger === 'object' && 'path' in handler.trigger) {
661
682
  const triggerPath = handler.trigger.path;
@@ -1409,6 +1430,7 @@ export function buildFunctionContext(options: BuildFunctionContextOptions): Func
1409
1430
  const ctx: FunctionContext = {
1410
1431
  request: options.request,
1411
1432
  auth: options.auth,
1433
+ db: admin.db,
1412
1434
  admin,
1413
1435
  params: options.params ?? {},
1414
1436
  };
@@ -149,6 +149,15 @@ export async function authMiddleware(c: Context<{ Bindings: Env }>, next: Next):
149
149
  c.set('auth', auth);
150
150
  return next();
151
151
  } catch (err) {
152
+ // In non-release (dev) mode, treat invalid/expired tokens as anonymous
153
+ // instead of hard-rejecting. This prevents stale tokens from blocking
154
+ // the demo/dev experience while still validating in production.
155
+ const config = parseConfig(c.env);
156
+ if (!config.release) {
157
+ c.set('auth', null);
158
+ return next();
159
+ }
160
+
152
161
  if (err instanceof TokenExpiredError) {
153
162
  return c.json(
154
163
  { code: 401, message: 'Token expired.', error: 'TOKEN_EXPIRED' },
@@ -41,7 +41,7 @@ type HonoEnv = { Bindings: Env };
41
41
 
42
42
  export const RATE_LIMIT_DEFAULTS: Record<string, { requests: number; windowSec: number }> = {
43
43
  global: { requests: 10_000_000, windowSec: 60 },
44
- db: { requests: 100, windowSec: 60 },
44
+ db: { requests: 100, windowSec: 60 },
45
45
  storage: { requests: 50, windowSec: 60 },
46
46
  functions: { requests: 50, windowSec: 60 },
47
47
  auth: { requests: 30, windowSec: 60 },
@@ -50,6 +50,19 @@ export const RATE_LIMIT_DEFAULTS: Record<string, { requests: number; windowSec:
50
50
  events: { requests: 100, windowSec: 60 },
51
51
  };
52
52
 
53
+ // Dev mode defaults: 10x higher to accommodate React strict mode double-rendering,
54
+ // hot-reload page refreshes, and onSnapshot polling during development.
55
+ export const RATE_LIMIT_DEV_DEFAULTS: Record<string, { requests: number; windowSec: number }> = {
56
+ global: { requests: 10_000_000, windowSec: 60 },
57
+ db: { requests: 1000, windowSec: 60 },
58
+ storage: { requests: 500, windowSec: 60 },
59
+ functions: { requests: 500, windowSec: 60 },
60
+ auth: { requests: 300, windowSec: 60 },
61
+ authSignin: { requests: 100, windowSec: 60 },
62
+ authSignup: { requests: 100, windowSec: 60 },
63
+ events: { requests: 1000, windowSec: 60 },
64
+ };
65
+
53
66
  // ─── Window parser ───
54
67
 
55
68
  /** Parse window string ('60s', '5m', '1h') or number (seconds) to seconds */
@@ -124,6 +137,11 @@ export class FixedWindowCounter {
124
137
  return Math.max(1, Math.ceil((bucket.resetAt - Date.now()) / 1000));
125
138
  }
126
139
 
140
+ /** Clear all buckets. Called when config changes to avoid stale limits blocking requests. */
141
+ reset(): void {
142
+ this.buckets.clear();
143
+ }
144
+
127
145
  private maybeCleanup(now: number): void {
128
146
  if (now - this.lastCleanup < FixedWindowCounter.CLEANUP_INTERVAL) return;
129
147
  this.lastCleanup = now;
@@ -139,7 +157,9 @@ export const counter = new FixedWindowCounter();
139
157
 
140
158
  // ─── Helpers ───
141
159
 
142
- /** Get config-based limit for a group, with fallback to defaults */
160
+ /** Get config-based limit for a group, with fallback to defaults.
161
+ * In dev mode (release !== true), uses relaxed defaults to avoid
162
+ * rate limiting during development with hot-reload and strict mode. */
143
163
  export function getLimit(
144
164
  config: EdgeBaseConfig | undefined,
145
165
  group: string,
@@ -154,7 +174,9 @@ export function getLimit(
154
174
  };
155
175
  }
156
176
  }
157
- return RATE_LIMIT_DEFAULTS[group] ?? { requests: 10_000_000, windowSec: 60 };
177
+ const isDevMode = config?.release !== true;
178
+ const defaults = isDevMode ? RATE_LIMIT_DEV_DEFAULTS : RATE_LIMIT_DEFAULTS;
179
+ return defaults[group] ?? { requests: 10_000_000, windowSec: 60 };
158
180
  }
159
181
 
160
182
  /** Map group name to the corresponding env binding */
@@ -22,7 +22,7 @@ import {
22
22
  export const databaseLiveRoute = new OpenAPIHono<HonoEnv>({ defaultHook: zodDefaultHook });
23
23
 
24
24
  const MAX_PENDING_PER_IP = 5;
25
- const PENDING_TTL_SECONDS = 10;
25
+ const PENDING_TTL_SECONDS = 60;
26
26
  const dbLiveQuerySchema = z.object({
27
27
  channel: z.string().optional().openapi({ description: 'Legacy DB subscription channel name' }),
28
28
  namespace: z.string().optional().openapi({ description: 'Database namespace', example: 'shared' }),
@@ -150,6 +150,14 @@ functionsRoute.all('/:functionName{.+}', async (c) => {
150
150
  }
151
151
 
152
152
  console.error(`[EdgeBase] HTTP function '${matched.route.name}' error:`, err);
153
- return c.json({ code: 500, message: 'Function execution failed.' }, 500);
153
+ const release = parseConfig(c.env)?.release ?? false;
154
+ return c.json({
155
+ code: 500,
156
+ message: 'Function execution failed.',
157
+ ...(!release && {
158
+ error: err instanceof Error ? err.message : String(err),
159
+ stack: err instanceof Error ? err.stack : undefined,
160
+ }),
161
+ }, 500);
154
162
  }
155
163
  });
@@ -6,7 +6,7 @@
6
6
  *
7
7
  * Supported actions:
8
8
  * upsert — Insert or replace vectors (write)
9
- * insert — Insert vectors, error on duplicate ID (write)
9
+ * insert — Insert new vectors without replacing existing IDs (write)
10
10
  * search — Similarity search by vector values (query)
11
11
  * queryById — Similarity search using an existing vector's ID (query, Vectorize v2 only)
12
12
  * getByIds — Retrieve vectors by ID (query)
@@ -17,8 +17,8 @@
17
17
  * - Config Allowlist: index must be declared in config.vectorize
18
18
  * - Service Key required with scoped validation
19
19
  *
20
- * Note: Vectorize is Cloudflare Edge-only. In local/Docker (Miniflare), the binding
21
- * will not exist the route returns a stub response with a warning.
20
+ * Note: Cloudflare does not provide a local Vectorize simulation. When the binding
21
+ * is unavailable in EdgeBase local or Docker environments, the route returns a stub response with a warning.
22
22
  *
23
23
  * Flow: Server SDK → POST /api/vectorize/:index → Worker → Vectorize binding → JSON
24
24
  */
@@ -161,7 +161,7 @@ vectorizeRoute.openapi(vectorizeOperation, async (c) => {
161
161
  // ─── Binding access ───────────────────────────────────────────────────
162
162
 
163
163
  // §1 Env type — dynamic binding access via type assertion
164
- // §7: Vectorize is Edge-only, Miniflare doesn't support it
164
+ // §7: Vectorize has no local simulation in Cloudflare. EdgeBase falls back to stubs.
165
165
  const bindingName = vectorConfig.binding ?? `VECTORIZE_${nameParam.toUpperCase()}`;
166
166
  const binding = (c.env as unknown as Record<string, unknown>)[bindingName] as VectorizeIndex | undefined;
167
167
  if (!binding) {
@@ -1 +0,0 @@
1
- var x=t=>{throw TypeError(t)};var B=(t,e,n)=>e.has(t)||x("Cannot "+n);var a=(t,e,n)=>(B(t,e,"read from private field"),n?n.call(t):e.get(t)),c=(t,e,n)=>e.has(t)?x("Cannot add the same private member more than once"):e instanceof WeakSet?e.add(t):e.set(t,n);import{w as G,o as I}from"./Bn2NtlTj.js";import{d as u,g as f,b as d}from"./BdTBlfLy.js";new URL("sveltekit-internal://");function se(t,e){return t==="/"||e==="ignore"?t:e==="never"?t.endsWith("/")?t.slice(0,-1):t:e==="always"&&!t.endsWith("/")?t+"/":t}function ae(t){return t.split("%25").map(decodeURI).join("%25")}function oe(t){for(const e in t)t[e]=decodeURIComponent(t[e]);return t}function ie({href:t}){return t.split("#")[0]}function W(...t){let e=5381;for(const n of t)if(typeof n=="string"){let r=n.length;for(;r;)e=e*33^n.charCodeAt(--r)}else if(ArrayBuffer.isView(n)){const r=new Uint8Array(n.buffer,n.byteOffset,n.byteLength);let s=r.length;for(;s;)e=e*33^r[--s]}else throw new TypeError("value must be a string or TypedArray");return(e>>>0).toString(36)}new TextEncoder;new TextDecoder;function X(t){const e=atob(t),n=new Uint8Array(e.length);for(let r=0;r<e.length;r++)n[r]=e.charCodeAt(r);return n}const z=window.fetch;window.fetch=(t,e)=>((t instanceof Request?t.method:(e==null?void 0:e.method)||"GET")!=="GET"&&b.delete(U(t)),z(t,e));const b=new Map;function le(t,e){const n=U(t,e),r=document.querySelector(n);if(r!=null&&r.textContent){r.remove();let{body:s,...l}=JSON.parse(r.textContent);const o=r.getAttribute("data-ttl");return o&&b.set(n,{body:s,init:l,ttl:1e3*Number(o)}),r.getAttribute("data-b64")!==null&&(s=X(s)),Promise.resolve(new Response(s,l))}return window.fetch(t,e)}function ce(t,e,n){if(b.size>0){const r=U(t,n),s=b.get(r);if(s){if(performance.now()<s.ttl&&["default","force-cache","only-if-cached",void 0].includes(n==null?void 0:n.cache))return new Response(s.body,s.init);b.delete(r)}}return window.fetch(e,n)}function U(t,e){let r=`script[data-sveltekit-fetched][data-url=${JSON.stringify(t instanceof Request?t.url:t)}]`;if(e!=null&&e.headers||e!=null&&e.body){const s=[];e.headers&&s.push([...new Headers(e.headers)].join(",")),e.body&&(typeof e.body=="string"||ArrayBuffer.isView(e.body))&&s.push(e.body),r+=`[data-hash="${W(...s)}"]`}return r}var $;const J=(($=globalThis.__sveltekit_1f6v8l6)==null?void 0:$.base)??"/admin";var C;const M=((C=globalThis.__sveltekit_1f6v8l6)==null?void 0:C.assets)??J??"",F="1773877838042",ue="sveltekit:snapshot",fe="sveltekit:scroll",de="sveltekit:states",he="sveltekit:pageurl",ge="sveltekit:history",be="sveltekit:navigation",N={tap:1,hover:2,viewport:3,eager:4,off:-1,false:-1},Y=location.origin;function _e(t){if(t instanceof URL)return t;let e=document.baseURI;if(!e){const n=document.getElementsByTagName("base");e=n.length?n[0].href:document.URL}return new URL(t,e)}function we(){return{x:pageXOffset,y:pageYOffset}}function g(t,e){return t.getAttribute(`data-sveltekit-${e}`)}const L={...N,"":N.hover};function q(t){let e=t.assignedSlot??t.parentNode;return(e==null?void 0:e.nodeType)===11&&(e=e.host),e}function me(t,e){for(;t&&t!==e;){if(t.nodeName.toUpperCase()==="A"&&t.hasAttribute("href"))return t;t=q(t)}}function ve(t,e,n){let r;try{if(r=new URL(t instanceof SVGAElement?t.href.baseVal:t.href,document.baseURI),n&&r.hash.match(/^#[^/]/)){const i=location.hash.split("#")[1]||"/";r.hash=`#${i}${r.hash}`}}catch{}const s=t instanceof SVGAElement?t.target.baseVal:t.target,l=!r||!!s||Q(r,e,n)||(t.getAttribute("rel")||"").split(/\s+/).includes("external"),o=(r==null?void 0:r.origin)===Y&&t.hasAttribute("download");return{url:r,external:l,target:s,download:o}}function pe(t){let e=null,n=null,r=null,s=null,l=null,o=null,i=t;for(;i&&i!==document.documentElement;)r===null&&(r=g(i,"preload-code")),s===null&&(s=g(i,"preload-data")),e===null&&(e=g(i,"keepfocus")),n===null&&(n=g(i,"noscroll")),l===null&&(l=g(i,"reload")),o===null&&(o=g(i,"replacestate")),i=q(i);function h(K){switch(K){case"":case"true":return!0;case"off":case"false":return!1;default:return}}return{preload_code:L[r??"off"],preload_data:L[s??"off"],keepfocus:h(e),noscroll:h(n),reload:h(l),replace_state:h(o)}}function ye(t){const e=G(t);let n=!0;function r(){n=!0,e.update(o=>o)}function s(o){n=!1,e.set(o)}function l(o){let i;return e.subscribe(h=>{(i===void 0||n&&h!==i)&&o(i=h)})}return{notify:r,set:s,subscribe:l}}const D={v:()=>{}};function Ae(){const{set:t,subscribe:e}=G(!1);let n;async function r(){clearTimeout(n);try{const s=await fetch(`${M}/_app/version.json`,{headers:{pragma:"no-cache","cache-control":"no-cache"}});if(!s.ok)return!1;const o=(await s.json()).version!==F;return o&&(t(!0),D.v(),clearTimeout(n)),o}catch{return!1}}return{subscribe:e,check:r}}function Q(t,e,n){return t.origin!==Y||!t.pathname.startsWith(e)?!0:n?t.pathname!==location.pathname:!1}function Re(t){}const H=new Set(["load","prerender","csr","ssr","trailingSlash","config"]);[...H];const Z=new Set([...H]);[...Z];let E,O,T;const ee=I.toString().includes("$$")||/function \w+\(\) \{\}/.test(I.toString());var _,w,m,v,p,y,A,R,P,S,V,k,j;ee?(E={data:{},form:null,error:null,params:{},route:{id:null},state:{},status:-1,url:new URL("https://example.com")},O={current:null},T={current:!1}):(E=new(P=class{constructor(){c(this,_,u({}));c(this,w,u(null));c(this,m,u(null));c(this,v,u({}));c(this,p,u({id:null}));c(this,y,u({}));c(this,A,u(-1));c(this,R,u(new URL("https://example.com")))}get data(){return f(a(this,_))}set data(e){d(a(this,_),e)}get form(){return f(a(this,w))}set form(e){d(a(this,w),e)}get error(){return f(a(this,m))}set error(e){d(a(this,m),e)}get params(){return f(a(this,v))}set params(e){d(a(this,v),e)}get route(){return f(a(this,p))}set route(e){d(a(this,p),e)}get state(){return f(a(this,y))}set state(e){d(a(this,y),e)}get status(){return f(a(this,A))}set status(e){d(a(this,A),e)}get url(){return f(a(this,R))}set url(e){d(a(this,R),e)}},_=new WeakMap,w=new WeakMap,m=new WeakMap,v=new WeakMap,p=new WeakMap,y=new WeakMap,A=new WeakMap,R=new WeakMap,P),O=new(V=class{constructor(){c(this,S,u(null))}get current(){return f(a(this,S))}set current(e){d(a(this,S),e)}},S=new WeakMap,V),T=new(j=class{constructor(){c(this,k,u(!1))}get current(){return f(a(this,k))}set current(e){d(a(this,k),e)}},k=new WeakMap,j),D.v=()=>T.current=!0);function Ee(t){Object.assign(E,t)}export{ge as H,be as N,he as P,de as S,pe as a,J as b,ie as c,oe as d,se as e,me as f,ve as g,Ae as h,Q as i,ye as j,N as k,ae as l,ue as m,O as n,Y as o,E as p,ce as q,_e as r,we as s,le as t,fe as u,Ee as v,Re as w};
@@ -1 +0,0 @@
1
- import{ab as J,bm as ee}from"./BdTBlfLy.js";import{w as ae}from"./Bn2NtlTj.js";import{H as N,N as M,r as gt,o as $t,i as _t,b as L,s as C,p as x,n as ft,f as Nt,g as ut,a as X,c as it,S as Dt,P as ne,d as re,e as oe,h as se,j as Pt,k as q,l as ie,m as qt,q as ce,t as le,u as Kt,v as fe}from"./B-pVQkKM.js";class wt{constructor(a,e){this.status=a,typeof e=="string"?this.body={message:e}:e?this.body=e:this.body={message:`Error: ${a}`}}toString(){return JSON.stringify(this.body)}}class vt{constructor(a,e){this.status=a,this.location=e}}class yt extends Error{constructor(a,e,r){super(r),this.status=a,this.text=e}}const ue=/^(\[)?(\.\.\.)?(\w+)(?:=(\w+))?(\])?$/;function he(t){const a=[];return{pattern:t==="/"?/^\/$/:new RegExp(`^${pe(t).map(r=>{const n=/^\[\.\.\.(\w+)(?:=(\w+))?\]$/.exec(r);if(n)return a.push({name:n[1],matcher:n[2],optional:!1,rest:!0,chained:!0}),"(?:/([^]*))?";const o=/^\[\[(\w+)(?:=(\w+))?\]\]$/.exec(r);if(o)return a.push({name:o[1],matcher:o[2],optional:!0,rest:!1,chained:!0}),"(?:/([^/]+))?";if(!r)return;const s=r.split(/\[(.+?)\](?!\])/);return"/"+s.map((c,l)=>{if(l%2){if(c.startsWith("x+"))return ct(String.fromCharCode(parseInt(c.slice(2),16)));if(c.startsWith("u+"))return ct(String.fromCharCode(...c.slice(2).split("-").map(_=>parseInt(_,16))));const h=ue.exec(c),[,u,w,f,d]=h;return a.push({name:f,matcher:d,optional:!!u,rest:!!w,chained:w?l===1&&s[0]==="":!1}),w?"([^]*?)":u?"([^/]*)?":"([^/]+?)"}return ct(c)}).join("")}).join("")}/?$`),params:a}}function de(t){return t!==""&&!/^\([^)]+\)$/.test(t)}function pe(t){return t.slice(1).split("/").filter(de)}function me(t,a,e){const r={},n=t.slice(1),o=n.filter(i=>i!==void 0);let s=0;for(let i=0;i<a.length;i+=1){const c=a[i];let l=n[i-s];if(c.chained&&c.rest&&s&&(l=n.slice(i-s,i+1).filter(h=>h).join("/"),s=0),l===void 0)if(c.rest)l="";else continue;if(!c.matcher||e[c.matcher](l)){r[c.name]=l;const h=a[i+1],u=n[i+1];h&&!h.rest&&h.optional&&u&&c.chained&&(s=0),!h&&!u&&Object.keys(r).length===o.length&&(s=0);continue}if(c.optional&&c.chained){s++;continue}return}if(!s)return r}function ct(t){return t.normalize().replace(/[[\]]/g,"\\$&").replace(/%/g,"%25").replace(/\//g,"%2[Ff]").replace(/\?/g,"%3[Ff]").replace(/#/g,"%23").replace(/[.*+?^${}()|\\]/g,"\\$&")}function ge({nodes:t,server_loads:a,dictionary:e,matchers:r}){const n=new Set(a);return Object.entries(e).map(([i,[c,l,h]])=>{const{pattern:u,params:w}=he(i),f={id:i,exec:d=>{const _=u.exec(d);if(_)return me(_,w,r)},errors:[1,...h||[]].map(d=>t[d]),layouts:[0,...l||[]].map(s),leaf:o(c)};return f.errors.length=f.layouts.length=Math.max(f.errors.length,f.layouts.length),f});function o(i){const c=i<0;return c&&(i=~i),[c,t[i]]}function s(i){return i===void 0?i:[n.has(i),t[i]]}}function Ft(t,a=JSON.parse){try{return a(sessionStorage[t])}catch{}}function It(t,a,e=JSON.stringify){const r=e(a);try{sessionStorage[t]=r}catch{}}function _e(t){return t.filter(a=>a!=null)}function bt(t){return t instanceof wt||t instanceof yt?t.status:500}function we(t){return t instanceof yt?t.text:"Internal Error"}const ve=new Set(["icon","shortcut icon","apple-touch-icon"]),I=Ft(Kt)??{},V=Ft(qt)??{},P={url:Pt({}),page:Pt({}),navigating:ae(null),updated:se()};function Et(t){I[t]=C()}function ye(t,a){let e=t+1;for(;I[e];)delete I[e],e+=1;for(e=a+1;V[e];)delete V[e],e+=1}function B(t,a=!1){return a?location.replace(t.href):location.href=t.href,new Promise(()=>{})}async function Mt(){if("serviceWorker"in navigator){const t=await navigator.serviceWorker.getRegistration(L||"/");t&&await t.update()}}function Tt(){}let kt,ht,Q,U,dt,E;const Z=[],tt=[];let v=null;function pt(){var t;(t=v==null?void 0:v.fork)==null||t.then(a=>a==null?void 0:a.discard()),v=null}const G=new Map,Vt=new Set,be=new Set,F=new Set;let g={branch:[],error:null,url:null},Bt=!1,et=!1,Ot=!0,H=!1,K=!1,Ht=!1,St=!1,Yt,b,R,O;const at=new Set,Ct=new Map;async function Fe(t,a,e){var o,s,i,c,l;(o=globalThis.__sveltekit_1f6v8l6)!=null&&o.data&&globalThis.__sveltekit_1f6v8l6.data,document.URL!==location.href&&(location.href=location.href),E=t,await((i=(s=t.hooks).init)==null?void 0:i.call(s)),kt=ge(t),U=document.documentElement,dt=a,ht=t.nodes[0],Q=t.nodes[1],ht(),Q(),b=(c=history.state)==null?void 0:c[N],R=(l=history.state)==null?void 0:l[M],b||(b=R=Date.now(),history.replaceState({...history.state,[N]:b,[M]:R},""));const r=I[b];function n(){r&&(history.scrollRestoration="manual",scrollTo(r.x,r.y))}e?(n(),await Ce(dt,e)):(await D({type:"enter",url:gt(E.hash?Ne(new URL(location.href)):location.href),replace_state:!0}),n()),Oe()}function Ee(){Z.length=0,St=!1}function zt(t){tt.some(a=>a==null?void 0:a.snapshot)&&(V[t]=tt.map(a=>{var e;return(e=a==null?void 0:a.snapshot)==null?void 0:e.capture()}))}function Wt(t){var a;(a=V[t])==null||a.forEach((e,r)=>{var n,o;(o=(n=tt[r])==null?void 0:n.snapshot)==null||o.restore(e)})}function jt(){Et(b),It(Kt,I),zt(R),It(qt,V)}async function Gt(t,a,e,r){let n;a.invalidateAll&&pt(),await D({type:"goto",url:gt(t),keepfocus:a.keepFocus,noscroll:a.noScroll,replace_state:a.replaceState,state:a.state,redirect_count:e,nav_token:r,accept:()=>{a.invalidateAll&&(St=!0,n=[...Ct.keys()]),a.invalidate&&a.invalidate.forEach(Te)}}),a.invalidateAll&&J().then(J).then(()=>{Ct.forEach(({resource:o},s)=>{var i;n!=null&&n.includes(s)&&((i=o.refresh)==null||i.call(o))})})}async function ke(t){if(t.id!==(v==null?void 0:v.id)){pt();const a={};at.add(a),v={id:t.id,token:a,promise:Xt({...t,preload:a}).then(e=>(at.delete(a),e.type==="loaded"&&e.state.error&&pt(),e)),fork:null}}return v.promise}async function lt(t){var e;const a=(e=await ot(t,!1))==null?void 0:e.route;a&&await Promise.all([...a.layouts,a.leaf].map(r=>r==null?void 0:r[1]()))}async function Jt(t,a,e){var n;g=t.state;const r=document.querySelector("style[data-sveltekit]");if(r&&r.remove(),Object.assign(x,t.props.page),Yt=new E.root({target:a,props:{...t.props,stores:P,components:tt},hydrate:e,sync:!1}),await Promise.resolve(),Wt(R),e){const o={from:null,to:{params:g.params,route:{id:((n=g.route)==null?void 0:n.id)??null},url:new URL(location.href),scroll:I[b]??C()},willUnload:!1,type:"enter",complete:Promise.resolve()};F.forEach(s=>s(o))}et=!0}function nt({url:t,params:a,branch:e,status:r,error:n,route:o,form:s}){let i="never";if(L&&(t.pathname===L||t.pathname===L+"/"))i="always";else for(const f of e)(f==null?void 0:f.slash)!==void 0&&(i=f.slash);t.pathname=oe(t.pathname,i),t.search=t.search;const c={type:"loaded",state:{url:t,params:a,branch:e,error:n,route:o},props:{constructors:_e(e).map(f=>f.node.component),page:At(x)}};s!==void 0&&(c.props.form=s);let l={},h=!x,u=0;for(let f=0;f<Math.max(e.length,g.branch.length);f+=1){const d=e[f],_=g.branch[f];(d==null?void 0:d.data)!==(_==null?void 0:_.data)&&(h=!0),d&&(l={...l,...d.data},h&&(c.props[`data_${u}`]=l),u+=1)}return(!g.url||t.href!==g.url.href||g.error!==n||s!==void 0&&s!==x.form||h)&&(c.props.page={error:n,params:a,route:{id:(o==null?void 0:o.id)??null},state:{},status:r,url:new URL(t),form:s??null,data:h?l:x.data}),c}async function Rt({loader:t,parent:a,url:e,params:r,route:n,server_data_node:o}){var l,h;let s=null;const i={dependencies:new Set,params:new Set,parent:!1,route:!1,url:!1,search_params:new Set},c=await t();return{node:c,loader:t,server:o,universal:(l=c.universal)!=null&&l.load?{type:"data",data:s,uses:i}:null,data:s??(o==null?void 0:o.data)??null,slash:((h=c.universal)==null?void 0:h.trailingSlash)??(o==null?void 0:o.slash)}}function Se(t,a,e){let r=t instanceof Request?t.url:t;const n=new URL(r,e);n.origin===e.origin&&(r=n.href.slice(e.origin.length));const o=et?ce(r,n.href,a):le(r,a);return{resolved:n,promise:o}}function Re(t,a,e,r,n,o){if(St)return!0;if(!n)return!1;if(n.parent&&t||n.route&&a||n.url&&e)return!0;for(const s of n.search_params)if(r.has(s))return!0;for(const s of n.params)if(o[s]!==g.params[s])return!0;for(const s of n.dependencies)if(Z.some(i=>i(new URL(s))))return!0;return!1}function xt(t,a){return(t==null?void 0:t.type)==="data"?t:(t==null?void 0:t.type)==="skip"?a??null:null}function xe(t,a){if(!t)return new Set(a.searchParams.keys());const e=new Set([...t.searchParams.keys(),...a.searchParams.keys()]);for(const r of e){const n=t.searchParams.getAll(r),o=a.searchParams.getAll(r);n.every(s=>o.includes(s))&&o.every(s=>n.includes(s))&&e.delete(r)}return e}function Le({error:t,url:a,route:e,params:r}){return{type:"loaded",state:{error:t,url:a,route:e,params:r,branch:[]},props:{page:At(x),constructors:[]}}}async function Xt({id:t,invalidating:a,url:e,params:r,route:n,preload:o}){if((v==null?void 0:v.id)===t)return at.delete(v.token),v.promise;const{errors:s,layouts:i,leaf:c}=n,l=[...i,c];s.forEach(m=>m==null?void 0:m().catch(()=>{})),l.forEach(m=>m==null?void 0:m[1]().catch(()=>{}));const h=g.url?t!==rt(g.url):!1,u=g.route?n.id!==g.route.id:!1,w=xe(g.url,e);let f=!1;const d=l.map(async(m,p)=>{var A;if(!m)return;const y=g.branch[p];return m[1]===(y==null?void 0:y.loader)&&!Re(f,u,h,w,(A=y.universal)==null?void 0:A.uses,r)?y:(f=!0,Rt({loader:m[1],url:e,params:r,route:n,parent:async()=>{var z;const T={};for(let j=0;j<p;j+=1)Object.assign(T,(z=await d[j])==null?void 0:z.data);return T},server_data_node:xt(m[0]?{type:"skip"}:null,m[0]?y==null?void 0:y.server:void 0)}))});for(const m of d)m.catch(()=>{});const _=[];for(let m=0;m<l.length;m+=1)if(l[m])try{_.push(await d[m])}catch(p){if(p instanceof vt)return{type:"redirect",location:p.location};if(at.has(o))return Le({error:await Y(p,{params:r,url:e,route:{id:n.id}}),url:e,params:r,route:n});let y=bt(p),S;if(p instanceof wt)S=p.body;else{if(await P.updated.check())return await Mt(),await B(e);S=await Y(p,{params:r,url:e,route:{id:n.id}})}const A=await Ue(m,_,s);return A?nt({url:e,params:r,branch:_.slice(0,A.idx).concat(A.node),status:y,error:S,route:n}):await Zt(e,{id:n.id},S,y)}else _.push(void 0);return nt({url:e,params:r,branch:_,status:200,error:null,route:n,form:a?void 0:null})}async function Ue(t,a,e){for(;t--;)if(e[t]){let r=t;for(;!a[r];)r-=1;try{return{idx:r+1,node:{node:await e[t](),loader:e[t],data:{},server:null,universal:null}}}catch{continue}}}async function Lt({status:t,error:a,url:e,route:r}){const n={};let o=null;try{const s=await Rt({loader:ht,url:e,params:n,route:r,parent:()=>Promise.resolve({}),server_data_node:xt(o)}),i={node:await Q(),loader:Q,universal:null,server:null,data:null};return nt({url:e,params:n,branch:[s,i],status:t,error:a,route:null})}catch(s){if(s instanceof vt)return Gt(new URL(s.location,location.href),{},0);throw s}}async function Ae(t){const a=t.href;if(G.has(a))return G.get(a);let e;try{const r=(async()=>{let n=await E.hooks.reroute({url:new URL(t),fetch:async(o,s)=>Se(o,s,t).promise})??t;if(typeof n=="string"){const o=new URL(t);E.hash?o.hash=n:o.pathname=n,n=o}return n})();G.set(a,r),e=await r}catch{G.delete(a);return}return e}async function ot(t,a){if(t&&!_t(t,L,E.hash)){const e=await Ae(t);if(!e)return;const r=Pe(e);for(const n of kt){const o=n.exec(r);if(o)return{id:rt(t),invalidating:a,route:n,params:re(o),url:t}}}}function Pe(t){return ie(E.hash?t.hash.replace(/^#/,"").replace(/[?#].+/,""):t.pathname.slice(L.length))||"/"}function rt(t){return(E.hash?t.hash.replace(/^#/,""):t.pathname)+t.search}function Qt({url:t,type:a,intent:e,delta:r,event:n,scroll:o}){let s=!1;const i=Ut(g,e,t,a,o??null);r!==void 0&&(i.navigation.delta=r),n!==void 0&&(i.navigation.event=n);const c={...i.navigation,cancel:()=>{s=!0,i.reject(new Error("navigation cancelled"))}};return H||Vt.forEach(l=>l(c)),s?null:i}async function D({type:t,url:a,popped:e,keepfocus:r,noscroll:n,replace_state:o,state:s={},redirect_count:i=0,nav_token:c={},accept:l=Tt,block:h=Tt,event:u}){var j;const w=O;O=c;const f=await ot(a,!1),d=t==="enter"?Ut(g,f,a,t):Qt({url:a,type:t,delta:e==null?void 0:e.delta,intent:f,scroll:e==null?void 0:e.scroll,event:u});if(!d){h(),O===c&&(O=w);return}const _=b,m=R;l(),H=!0,et&&d.navigation.type!=="enter"&&P.navigating.set(ft.current=d.navigation);let p=f&&await Xt(f);if(!p){if(_t(a,L,E.hash))return await B(a,o);p=await Zt(a,{id:null},await Y(new yt(404,"Not Found",`Not found: ${a.pathname}`),{url:a,params:{},route:{id:null}}),404,o)}if(a=(f==null?void 0:f.url)||a,O!==c)return d.reject(new Error("navigation aborted")),!1;if(p.type==="redirect"){if(i<20){await D({type:t,url:new URL(p.location,a),popped:e,keepfocus:r,noscroll:n,replace_state:o,state:s,redirect_count:i+1,nav_token:c}),d.fulfil(void 0);return}p=await Lt({status:500,error:await Y(new Error("Redirect loop"),{url:a,params:{},route:{id:null}}),url:a,route:{id:null}})}else p.props.page.status>=400&&await P.updated.check()&&(await Mt(),await B(a,o));if(Ee(),Et(_),zt(m),p.props.page.url.pathname!==a.pathname&&(a.pathname=p.props.page.url.pathname),s=e?e.state:s,!e){const k=o?0:1,W={[N]:b+=k,[M]:R+=k,[Dt]:s};(o?history.replaceState:history.pushState).call(history,W,"",a),o||ye(b,R)}const y=f&&(v==null?void 0:v.id)===f.id?v.fork:null;v=null,p.props.page.state=s;let S;if(et){const k=(await Promise.all(Array.from(be,$=>$(d.navigation)))).filter($=>typeof $=="function");if(k.length>0){let $=function(){k.forEach(st=>{F.delete(st)})};k.push($),k.forEach(st=>{F.add(st)})}g=p.state,p.props.page&&(p.props.page.url=a);const W=y&&await y;W?S=W.commit():(Yt.$set(p.props),fe(p.props.page),S=(j=ee)==null?void 0:j()),Ht=!0}else await Jt(p,dt,!1);const{activeElement:A}=document;await S,await J(),await J();let T=null;if(Ot){const k=e?e.scroll:n?C():null;k?scrollTo(k.x,k.y):(T=a.hash&&document.getElementById(te(a)))?T.scrollIntoView():scrollTo(0,0)}const z=document.activeElement!==A&&document.activeElement!==document.body;!r&&!z&&$e(a,!T),Ot=!0,p.props.page&&Object.assign(x,p.props.page),H=!1,t==="popstate"&&Wt(R),d.fulfil(void 0),d.navigation.to&&(d.navigation.to.scroll=C()),F.forEach(k=>k(d.navigation)),P.navigating.set(ft.current=null)}async function Zt(t,a,e,r,n){return t.origin===$t&&t.pathname===location.pathname&&!Bt?await Lt({status:r,error:e,url:t,route:a}):await B(t,n)}function Ie(){let t,a={element:void 0,href:void 0},e;U.addEventListener("mousemove",i=>{const c=i.target;clearTimeout(t),t=setTimeout(()=>{o(c,q.hover)},20)});function r(i){i.defaultPrevented||o(i.composedPath()[0],q.tap)}U.addEventListener("mousedown",r),U.addEventListener("touchstart",r,{passive:!0});const n=new IntersectionObserver(i=>{for(const c of i)c.isIntersecting&&(lt(new URL(c.target.href)),n.unobserve(c.target))},{threshold:0});async function o(i,c){const l=Nt(i,U),h=l===a.element&&(l==null?void 0:l.href)===a.href&&c>=e;if(!l||h)return;const{url:u,external:w,download:f}=ut(l,L,E.hash);if(w||f)return;const d=X(l),_=u&&rt(g.url)===rt(u);if(!(d.reload||_))if(c<=d.preload_data){a={element:l,href:l.href},e=q.tap;const m=await ot(u,!1);if(!m)return;ke(m)}else c<=d.preload_code&&(a={element:l,href:l.href},e=c,lt(u))}function s(){n.disconnect();for(const i of U.querySelectorAll("a")){const{url:c,external:l,download:h}=ut(i,L,E.hash);if(l||h)continue;const u=X(i);u.reload||(u.preload_code===q.viewport&&n.observe(i),u.preload_code===q.eager&&lt(c))}}F.add(s),s()}function Y(t,a){if(t instanceof wt)return t.body;const e=bt(t),r=we(t);return E.hooks.handleError({error:t,event:a,status:e,message:r})??{message:r}}function Me(t,a={}){return t=new URL(gt(t)),t.origin!==$t?Promise.reject(new Error("goto: invalid URL")):Gt(t,a,0)}function Te(t){if(typeof t=="function")Z.push(t);else{const{href:a}=new URL(t,location.href);Z.push(e=>e.href===a)}}function Oe(){var a;history.scrollRestoration="manual",addEventListener("beforeunload",e=>{let r=!1;if(jt(),!H){const n=Ut(g,void 0,null,"leave"),o={...n.navigation,cancel:()=>{r=!0,n.reject(new Error("navigation cancelled"))}};Vt.forEach(s=>s(o))}r?(e.preventDefault(),e.returnValue=""):history.scrollRestoration="auto"}),addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"&&jt()}),(a=navigator.connection)!=null&&a.saveData||Ie(),U.addEventListener("click",async e=>{if(e.button||e.which!==1||e.metaKey||e.ctrlKey||e.shiftKey||e.altKey||e.defaultPrevented)return;const r=Nt(e.composedPath()[0],U);if(!r)return;const{url:n,external:o,target:s,download:i}=ut(r,L,E.hash);if(!n)return;if(s==="_parent"||s==="_top"){if(window.parent!==window)return}else if(s&&s!=="_self")return;const c=X(r);if(!(r instanceof SVGAElement)&&n.protocol!==location.protocol&&!(n.protocol==="https:"||n.protocol==="http:")||i)return;const[h,u]=(E.hash?n.hash.replace(/^#/,""):n.href).split("#"),w=h===it(location);if(o||c.reload&&(!w||!u)){Qt({url:n,type:"link",event:e})?H=!0:e.preventDefault();return}if(u!==void 0&&w){const[,f]=g.url.href.split("#");if(f===u){if(e.preventDefault(),u===""||u==="top"&&r.ownerDocument.getElementById("top")===null)scrollTo({top:0});else{const d=r.ownerDocument.getElementById(decodeURIComponent(u));d&&(d.scrollIntoView(),d.focus())}return}if(K=!0,Et(b),t(n),!c.replace_state)return;K=!1}e.preventDefault(),await new Promise(f=>{requestAnimationFrame(()=>{setTimeout(f,0)}),setTimeout(f,100)}),await D({type:"link",url:n,keepfocus:c.keepfocus,noscroll:c.noscroll,replace_state:c.replace_state??n.href===location.href,event:e})}),U.addEventListener("submit",e=>{if(e.defaultPrevented)return;const r=HTMLFormElement.prototype.cloneNode.call(e.target),n=e.submitter;if(((n==null?void 0:n.formTarget)||r.target)==="_blank"||((n==null?void 0:n.formMethod)||r.method)!=="get")return;const i=new URL((n==null?void 0:n.hasAttribute("formaction"))&&(n==null?void 0:n.formAction)||r.action);if(_t(i,L,!1))return;const c=e.target,l=X(c);if(l.reload)return;e.preventDefault(),e.stopPropagation();const h=new FormData(c,n);i.search=new URLSearchParams(h).toString(),D({type:"form",url:i,keepfocus:l.keepfocus,noscroll:l.noscroll,replace_state:l.replace_state??i.href===location.href,event:e})}),addEventListener("popstate",async e=>{var r;if(!mt){if((r=e.state)!=null&&r[N]){const n=e.state[N];if(O={},n===b)return;const o=I[n],s=e.state[Dt]??{},i=new URL(e.state[ne]??location.href),c=e.state[M],l=g.url?it(location)===it(g.url):!1;if(c===R&&(Ht||l)){s!==x.state&&(x.state=s),t(i),I[b]=C(),o&&scrollTo(o.x,o.y),b=n;return}const u=n-b;await D({type:"popstate",url:i,popped:{state:s,scroll:o,delta:u},accept:()=>{b=n,R=c},block:()=>{history.go(-u)},nav_token:O,event:e})}else if(!K){const n=new URL(location.href);t(n),E.hash&&location.reload()}}}),addEventListener("hashchange",()=>{K&&(K=!1,history.replaceState({...history.state,[N]:++b,[M]:R},"",location.href))});for(const e of document.querySelectorAll("link"))ve.has(e.rel)&&(e.href=e.href);addEventListener("pageshow",e=>{e.persisted&&P.navigating.set(ft.current=null)});function t(e){g.url=x.url=e,P.page.set(At(x)),P.page.notify()}}async function Ce(t,{status:a=200,error:e,node_ids:r,params:n,route:o,server_route:s,data:i,form:c}){Bt=!0;const l=new URL(location.href);let h;({params:n={},route:o={id:null}}=await ot(l,!1)||{}),h=kt.find(({id:f})=>f===o.id);let u,w=!0;try{const f=r.map(async(_,m)=>{const p=i[m];return p!=null&&p.uses&&(p.uses=je(p.uses)),Rt({loader:E.nodes[_],url:l,params:n,route:o,parent:async()=>{const y={};for(let S=0;S<m;S+=1)Object.assign(y,(await f[S]).data);return y},server_data_node:xt(p)})}),d=await Promise.all(f);if(h){const _=h.layouts;for(let m=0;m<_.length;m++)_[m]||d.splice(m,0,void 0)}u=nt({url:l,params:n,branch:d,status:a,error:e,form:c,route:h??null})}catch(f){if(f instanceof vt){await B(new URL(f.location,location.href));return}u=await Lt({status:bt(f),error:await Y(f,{url:l,params:n,route:o}),url:l,route:o}),t.textContent="",w=!1}u.props.page&&(u.props.page.state={}),await Jt(u,t,w)}function je(t){return{dependencies:new Set((t==null?void 0:t.dependencies)??[]),params:new Set((t==null?void 0:t.params)??[]),parent:!!(t!=null&&t.parent),route:!!(t!=null&&t.route),url:!!(t!=null&&t.url),search_params:new Set((t==null?void 0:t.search_params)??[])}}let mt=!1;function $e(t,a=!0){const e=document.querySelector("[autofocus]");if(e)e.focus();else{const r=te(t);if(r&&document.getElementById(r)){const{x:o,y:s}=C();setTimeout(()=>{const i=history.state;mt=!0,location.replace(new URL(`#${r}`,location.href)),history.replaceState(i,"",t),a&&scrollTo(o,s),mt=!1})}else{const o=document.body,s=o.getAttribute("tabindex");o.tabIndex=-1,o.focus({preventScroll:!0,focusVisible:!1}),s!==null?o.setAttribute("tabindex",s):o.removeAttribute("tabindex")}const n=getSelection();if(n&&n.type!=="None"){const o=[];for(let s=0;s<n.rangeCount;s+=1)o.push(n.getRangeAt(s));setTimeout(()=>{if(n.rangeCount===o.length){for(let s=0;s<n.rangeCount;s+=1){const i=o[s],c=n.getRangeAt(s);if(i.commonAncestorContainer!==c.commonAncestorContainer||i.startContainer!==c.startContainer||i.endContainer!==c.endContainer||i.startOffset!==c.startOffset||i.endOffset!==c.endOffset)return}n.removeAllRanges()}})}}}function Ut(t,a,e,r,n=null){var l,h;let o,s;const i=new Promise((u,w)=>{o=u,s=w});return i.catch(()=>{}),{navigation:{from:{params:t.params,route:{id:((l=t.route)==null?void 0:l.id)??null},url:t.url,scroll:C()},to:e&&{params:(a==null?void 0:a.params)??null,route:{id:((h=a==null?void 0:a.route)==null?void 0:h.id)??null},url:e,scroll:n},willUnload:!a,type:r,complete:i},fulfil:o,reject:s}}function At(t){return{data:t.data,error:t.error,form:t.form,params:t.params,route:t.route,state:t.state,status:t.status,url:t.url}}function Ne(t){const a=new URL(t);return a.hash=decodeURIComponent(t.hash),a}function te(t){let a;if(E.hash){const[,,e]=t.hash.split("#",3);a=e??""}else a=t.hash.slice(1);return decodeURIComponent(a)}export{Fe as a,Me as g,P as s};
@@ -1 +0,0 @@
1
- import{a as r}from"../chunks/WtDa8jKW.js";import{w as t}from"../chunks/B-pVQkKM.js";export{t as load_css,r as start};
@@ -1 +0,0 @@
1
- import{_ as m}from"../chunks/BvukSxhJ.js";export{m as component};