forked from deco-cx/deco
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdeco.ts
113 lines (99 loc) · 2.8 KB
/
deco.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/// <reference no-default-lib="true"/>
/// <reference lib="deno.ns" />
/// <reference lib="esnext" />
/// <reference lib="dom" />
/// <reference lib="dom.iterable" />
import "./utils/patched_fetch.ts";
import { AsyncLocalStorage } from "node:async_hooks";
import type { ImportMap } from "./blocks/app.ts";
import type { ReleaseResolver } from "./engine/core/mod.ts";
import type { DecofileProvider } from "./engine/decofile/provider.ts";
import type { AppManifest } from "./mod.ts";
import { randId } from "./utils/rand.ts";
export interface DecoRuntimeState {
manifest: AppManifest;
// deno-lint-ignore no-explicit-any
resolver: ReleaseResolver<any>;
importMap: ImportMap;
}
export interface InstanceInfo {
startedAt: Date;
id: string;
readyAt?: Date;
}
export type RequestContext = {
/** Cancelation token used for early processing halt */
signal?: AbortSignal;
framework?: "fresh" | "htmx";
};
// The global deco context
export type DecoContext = {
deploymentId: string | undefined;
isDeploy: boolean;
platform: string;
site: string;
siteId: number;
loginUrl?: string;
base?: string;
namespace?: string;
release?: DecofileProvider;
runtime?: Promise<DecoRuntimeState>;
play?: boolean;
instance: InstanceInfo;
request?: RequestContext;
};
const isDeploy = Boolean(Deno.env.get("DENO_DEPLOYMENT_ID"));
const getCloudProvider = () => {
const kService = Deno.env.get("K_SERVICE") !== undefined;
if (kService) {
return "kubernetes";
} else if (isDeploy) {
return "deno_deploy";
} else {
return "localhost";
}
};
const defaultContext: Omit<DecoContext, "schema"> = {
deploymentId: Deno.env.get("DENO_DEPLOYMENT_ID"),
isDeploy: isDeploy,
platform: getCloudProvider(),
site: "",
siteId: 0,
play: Deno.env.has("USE_LOCAL_STORAGE_ONLY"),
instance: {
id: randId(),
startedAt: new Date(),
},
};
const asyncLocalStorage = new AsyncLocalStorage<DecoContext>();
export const Context = {
// Function to retrieve the active context
active: (): DecoContext => {
// Retrieve the context associated with the async ID
return asyncLocalStorage.getStore() ?? defaultContext;
},
bind: <R, TArgs extends unknown[]>(
ctx: DecoContext,
f: (...args: TArgs) => R,
): (...args: TArgs) => R => {
return (...args: TArgs): R => {
return asyncLocalStorage.run(ctx, f, ...args);
};
},
};
export const RequestContext = {
active: () => Context.active().request,
bind: <R, TArgs extends unknown[]>(
request: RequestContext,
f: (...args: TArgs) => R,
): (...args: TArgs) => R => {
return Context.bind({ ...Context.active(), request }, f);
},
get signal() {
return Context.active().request?.signal;
},
get framework() {
return Context.active().request?.framework ?? "fresh";
},
};
export const context = Context.active();