@jami-studio/core 0.92.26 → 0.92.28
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/corpus/README.md +1 -1
- package/corpus/core/CHANGELOG.md +23 -0
- package/corpus/core/package.json +2 -1
- package/corpus/core/src/deploy/build.ts +56 -2
- package/corpus/core/src/event-bus/bus.ts +138 -140
- package/corpus/core/src/event-bus/registry.ts +81 -79
- package/corpus/core/src/file-upload/registry.ts +135 -125
- package/corpus/core/src/notifications/registry.ts +218 -216
- package/corpus/core/src/observability/store.ts +1313 -1321
- package/corpus/core/src/private-blob/registry.ts +246 -242
- package/corpus/core/src/secrets/register.ts +132 -129
- package/corpus/core/src/shared/global-scope.ts +75 -0
- package/corpus/core/src/shared/init-memo.ts +94 -0
- package/corpus/core/src/sharing/registry.ts +193 -194
- package/corpus/core/src/tracking/providers.ts +425 -422
- package/corpus/core/src/tracking/registry.ts +102 -102
- package/dist/collab/routes.d.ts +1 -1
- package/dist/deploy/build.d.ts +23 -0
- package/dist/deploy/build.d.ts.map +1 -1
- package/dist/deploy/build.js +36 -2
- package/dist/deploy/build.js.map +1 -1
- package/dist/event-bus/bus.d.ts.map +1 -1
- package/dist/event-bus/bus.js +8 -6
- package/dist/event-bus/bus.js.map +1 -1
- package/dist/event-bus/registry.d.ts.map +1 -1
- package/dist/event-bus/registry.js +10 -6
- package/dist/event-bus/registry.js.map +1 -1
- package/dist/file-upload/actions/upload-image.d.ts +1 -1
- package/dist/file-upload/registry.d.ts.map +1 -1
- package/dist/file-upload/registry.js +28 -8
- package/dist/file-upload/registry.js.map +1 -1
- package/dist/notifications/registry.d.ts.map +1 -1
- package/dist/notifications/registry.js +6 -5
- package/dist/notifications/registry.js.map +1 -1
- package/dist/observability/routes.d.ts +5 -5
- package/dist/observability/store.d.ts +1 -1
- package/dist/observability/store.d.ts.map +1 -1
- package/dist/observability/store.js +311 -316
- package/dist/observability/store.js.map +1 -1
- package/dist/private-blob/registry.d.ts.map +1 -1
- package/dist/private-blob/registry.js +18 -13
- package/dist/private-blob/registry.js.map +1 -1
- package/dist/progress/routes.d.ts +1 -1
- package/dist/resources/handlers.d.ts +2 -2
- package/dist/secrets/register.d.ts.map +1 -1
- package/dist/secrets/register.js +11 -7
- package/dist/secrets/register.js.map +1 -1
- package/dist/secrets/routes.d.ts +9 -9
- package/dist/shared/global-scope.d.ts +55 -0
- package/dist/shared/global-scope.d.ts.map +1 -0
- package/dist/shared/global-scope.js +70 -0
- package/dist/shared/global-scope.js.map +1 -0
- package/dist/shared/init-memo.d.ts +34 -0
- package/dist/shared/init-memo.d.ts.map +1 -0
- package/dist/shared/init-memo.js +80 -0
- package/dist/shared/init-memo.js.map +1 -0
- package/dist/sharing/registry.d.ts.map +1 -1
- package/dist/sharing/registry.js +2 -16
- package/dist/sharing/registry.js.map +1 -1
- package/dist/tracking/providers.d.ts.map +1 -1
- package/dist/tracking/providers.js +11 -9
- package/dist/tracking/providers.js.map +1 -1
- package/dist/tracking/registry.d.ts.map +1 -1
- package/dist/tracking/registry.js +5 -5
- package/dist/tracking/registry.js.map +1 -1
- package/package.json +2 -1
|
@@ -1,125 +1,135 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
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
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
);
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
|
|
1
|
+
import { getScopedGlobal } from "../shared/global-scope.js";
|
|
2
|
+
import { builderFileUploadProvider } from "./builder.js";
|
|
3
|
+
import type {
|
|
4
|
+
FileUploadInput,
|
|
5
|
+
FileUploadProvider,
|
|
6
|
+
FileUploadResult,
|
|
7
|
+
} from "./types.js";
|
|
8
|
+
|
|
9
|
+
// Why globalThis: in dev (Vite HMR) and in some Nitro/Rollup bundle splits,
|
|
10
|
+
// this module can be evaluated more than once — the plugin file that
|
|
11
|
+
// registers a provider lands in one module instance and the request handler
|
|
12
|
+
// that reads providers lands in another, so the call site sees an empty map
|
|
13
|
+
// even though `registerFileUploadProvider` succeeded. Pinning the singletons
|
|
14
|
+
// on `globalThis` guarantees one set of providers per Node process,
|
|
15
|
+
// independent of how the bundler split the chunks.
|
|
16
|
+
//
|
|
17
|
+
// Why scope-aware + lazy: on a unified workspace deployment every app shares
|
|
18
|
+
// one isolate, so a raw globalThis pin would merge every app's providers into
|
|
19
|
+
// one map (an /assets upload was served by clips' provider). The keys are
|
|
20
|
+
// namespaced per app via `getScopedGlobal`, resolved lazily on every access
|
|
21
|
+
// so the scope id set by the generated worker entry is always honored.
|
|
22
|
+
function getProviders(): Map<string, FileUploadProvider> {
|
|
23
|
+
return getScopedGlobal(
|
|
24
|
+
"agent-native.file-upload.providers",
|
|
25
|
+
() => new Map<string, FileUploadProvider>(),
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
function getWarnedFallbackRef(): { value: boolean } {
|
|
29
|
+
return getScopedGlobal("agent-native.file-upload.warned-fallback", () => ({
|
|
30
|
+
value: false,
|
|
31
|
+
}));
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Register a file upload provider. Call from a server plugin or app
|
|
36
|
+
* bootstrap. Idempotent per id — later calls with the same id replace.
|
|
37
|
+
*/
|
|
38
|
+
export function registerFileUploadProvider(provider: FileUploadProvider): void {
|
|
39
|
+
getProviders().set(provider.id, provider);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function unregisterFileUploadProvider(id: string): void {
|
|
43
|
+
getProviders().delete(id);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function listFileUploadProviders(): FileUploadProvider[] {
|
|
47
|
+
return [...getProviders().values()];
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Returns the first configured provider, checking user-registered ones first
|
|
52
|
+
* and falling back to the built-in Builder.io provider when its env is set.
|
|
53
|
+
* Returns `null` when nothing is configured — callers should then use the
|
|
54
|
+
* SQL fallback.
|
|
55
|
+
*/
|
|
56
|
+
export function getActiveFileUploadProvider(): FileUploadProvider | null {
|
|
57
|
+
for (const provider of getProviders().values()) {
|
|
58
|
+
if (provider.isConfigured()) return provider;
|
|
59
|
+
}
|
|
60
|
+
if (builderFileUploadProvider.isConfigured()) {
|
|
61
|
+
return builderFileUploadProvider;
|
|
62
|
+
}
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export async function getActiveFileUploadProviderForRequest(): Promise<FileUploadProvider | null> {
|
|
67
|
+
for (const provider of getProviders().values()) {
|
|
68
|
+
if (provider.isConfigured()) return provider;
|
|
69
|
+
if (provider.isConfiguredForRequest) {
|
|
70
|
+
try {
|
|
71
|
+
if (await provider.isConfiguredForRequest()) return provider;
|
|
72
|
+
} catch {
|
|
73
|
+
// Treat failed scoped credential lookups as unavailable. The upload
|
|
74
|
+
// call will surface real provider errors after a provider is selected.
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
if (builderFileUploadProvider.isConfigured()) {
|
|
79
|
+
return builderFileUploadProvider;
|
|
80
|
+
}
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Upload a file via the active provider, or `null` if no provider is
|
|
86
|
+
* configured. Callers use `null` as the signal to fall back to SQL
|
|
87
|
+
* storage. On the first fallback we log a one-time warning because
|
|
88
|
+
* storing files in SQL is not optimal for production.
|
|
89
|
+
*/
|
|
90
|
+
export async function uploadFile(
|
|
91
|
+
input: FileUploadInput,
|
|
92
|
+
): Promise<FileUploadResult | null> {
|
|
93
|
+
const provider = await getActiveFileUploadProviderForRequest();
|
|
94
|
+
// User-registered providers (S3, etc.) may be configured by sync runtime
|
|
95
|
+
// state or request-scoped DB secrets. Builder still gets an explicit async
|
|
96
|
+
// credential check below because its sync isConfigured() only checks env.
|
|
97
|
+
if (provider && provider !== builderFileUploadProvider) {
|
|
98
|
+
return provider.upload(input);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Resolve credentials asynchronously (works when request context is set
|
|
102
|
+
// via runWithRequestContext — actions always have one via action-routes.ts).
|
|
103
|
+
// Two separate try-catch blocks ensure a real upload failure is never
|
|
104
|
+
// silently swallowed as a "no credentials" case.
|
|
105
|
+
let builderKey: string | null = null;
|
|
106
|
+
try {
|
|
107
|
+
const { resolveBuilderPrivateKey } =
|
|
108
|
+
await import("../server/credential-provider.js");
|
|
109
|
+
builderKey = await resolveBuilderPrivateKey();
|
|
110
|
+
} catch (err) {
|
|
111
|
+
// DB unavailable or credential store not ready — can't resolve key.
|
|
112
|
+
// Log and fall through to the SQL fallback below.
|
|
113
|
+
console.warn(
|
|
114
|
+
"[agent-native] Builder credential check failed:",
|
|
115
|
+
err instanceof Error ? err.message : String(err),
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (builderKey) {
|
|
120
|
+
// Credentials confirmed — attempt the upload. Real errors (network,
|
|
121
|
+
// API, rate-limit) propagate to the caller; do NOT catch them here.
|
|
122
|
+
return await builderFileUploadProvider.upload(input);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const warnedFallbackRef = getWarnedFallbackRef();
|
|
126
|
+
if (!warnedFallbackRef.value) {
|
|
127
|
+
warnedFallbackRef.value = true;
|
|
128
|
+
console.warn(
|
|
129
|
+
"[agent-native] No file upload provider configured. " +
|
|
130
|
+
"Connect or reconnect Builder.io in Settings → File uploads, " +
|
|
131
|
+
"or register a custom provider (S3, R2, GCS, …) via registerFileUploadProvider().",
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
return null;
|
|
135
|
+
}
|