@bounded-sh/core 0.0.1 → 0.0.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/dist/client/config.d.ts +1 -1
- package/dist/client/operations.d.ts +1 -1
- package/dist/client/subscription-v2.d.ts +1 -1
- package/dist/client/subscription.d.ts +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +41 -41
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +41 -41
- package/dist/index.mjs.map +1 -1
- package/dist/utils/api.d.ts +1 -1
- package/dist/utils/core-platform.d.ts +1 -1
- package/dist/utils/rn-session-manager.d.ts +1 -1
- package/dist/utils/web-session-manager.d.ts +1 -1
- package/package.json +1 -1
package/dist/client/config.d.ts
CHANGED
|
@@ -96,7 +96,7 @@ export declare function getWebhookKeysUrl(): string | undefined;
|
|
|
96
96
|
/**
|
|
97
97
|
* True when init() configured a Bounded network (the Cloudflare-native stack).
|
|
98
98
|
* Synchronous + non-blocking. Used to route reads/writes that behave differently
|
|
99
|
-
* on Bounded vs the legacy
|
|
99
|
+
* on Bounded vs the legacy backend (e.g. `count`/`aggregate`, which on
|
|
100
100
|
* Bounded must use the deterministic server aggregation, not the legacy AI query).
|
|
101
101
|
*/
|
|
102
102
|
export declare function isBoundedNetwork(): boolean;
|
|
@@ -91,7 +91,7 @@ export type AggregateOptions = {
|
|
|
91
91
|
* Count items in a collection path. Returns a numeric result.
|
|
92
92
|
*
|
|
93
93
|
* This uses the AI query engine with a count-specific prompt prefix,
|
|
94
|
-
* so
|
|
94
|
+
* so Bounded will generate a $count aggregation pipeline and return
|
|
95
95
|
* just the count rather than full documents.
|
|
96
96
|
*
|
|
97
97
|
* IMPORTANT: This only works for collections where the read policy is "true".
|
|
@@ -87,6 +87,6 @@ export declare function wsDelete(path: string): Promise<any>;
|
|
|
87
87
|
export declare function wsGetMany(paths: string[]): Promise<any>;
|
|
88
88
|
declare global {
|
|
89
89
|
interface Window {
|
|
90
|
-
|
|
90
|
+
CUSTOM_BOUNDED_APP_ID_HEADER?: string;
|
|
91
91
|
}
|
|
92
92
|
}
|
|
@@ -59,6 +59,6 @@ export declare function getCachedData(path: string, prompt?: string): any | null
|
|
|
59
59
|
export declare function reconnectWithNewAuth(): Promise<void>;
|
|
60
60
|
declare global {
|
|
61
61
|
interface Window {
|
|
62
|
-
|
|
62
|
+
CUSTOM_BOUNDED_APP_ID_HEADER?: string;
|
|
63
63
|
}
|
|
64
64
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -16,8 +16,8 @@ export { getActiveSessionManager } from './utils/session-manager';
|
|
|
16
16
|
export type { ClientSessionManager } from './utils/session-manager';
|
|
17
17
|
export { ServerSessionManager } from './utils/server-session-manager';
|
|
18
18
|
export { createSessionWithSignature, refreshSession, revokeSession, signSessionCreateMessage, genAuthNonce } from './utils/auth-api';
|
|
19
|
-
export { Tarobase as
|
|
20
|
-
export { Tarobase as
|
|
19
|
+
export { Tarobase as Bounded6 } from './utils/sol/taro6CvKqwrYrDc16ufYgzQ2NZcyyVKStffbtudrhRuDevnet-program';
|
|
20
|
+
export { Tarobase as BoundedPoof } from './utils/sol/poof4b5pk1L9tmThvBmaABjcyjfhFGbMbQP5BXk2QZpMainnet-program';
|
|
21
21
|
export { buildSetDocumentsTransaction, convertRemainingAccounts, RemainingAccount, genSolanaMessage } from './utils/sol/sol-utils';
|
|
22
22
|
export { RealtimeStore, getRealtimeStore, resetRealtimeStore } from './client/realtime-store';
|
|
23
23
|
export type { StorageTier, SubscriptionStatus, SubscriptionState, SubscribeOptions, DeltaChange } from './client/realtime-store';
|
package/dist/index.js
CHANGED
|
@@ -95,7 +95,7 @@ function getWebhookKeysUrl() {
|
|
|
95
95
|
/**
|
|
96
96
|
* True when init() configured a Bounded network (the Cloudflare-native stack).
|
|
97
97
|
* Synchronous + non-blocking. Used to route reads/writes that behave differently
|
|
98
|
-
* on Bounded vs the legacy
|
|
98
|
+
* on Bounded vs the legacy backend (e.g. `count`/`aggregate`, which on
|
|
99
99
|
* Bounded must use the deterministic server aggregation, not the legacy AI query).
|
|
100
100
|
*/
|
|
101
101
|
function isBoundedNetwork() {
|
|
@@ -2950,7 +2950,7 @@ class WebSessionManager {
|
|
|
2950
2950
|
// the RIGHT /session/refresh. Email overrides with humanAuthApiUrl; all
|
|
2951
2951
|
// wallet/guest/signature flows default to authApiUrl (the bounded-auth issuer).
|
|
2952
2952
|
const sessionIssuer = (issuer || config.authApiUrl || "").replace(/\/$/, "");
|
|
2953
|
-
localStorage.setItem(this.
|
|
2953
|
+
localStorage.setItem(this.BOUNDED_SESSION_STORAGE_KEY, JSON.stringify(Object.assign({ address,
|
|
2954
2954
|
accessToken,
|
|
2955
2955
|
idToken,
|
|
2956
2956
|
refreshToken, appId: currentAppId }, (sessionIssuer ? { issuer: sessionIssuer } : {}))));
|
|
@@ -2961,7 +2961,7 @@ class WebSessionManager {
|
|
|
2961
2961
|
static async getSession() {
|
|
2962
2962
|
if (typeof window === "undefined")
|
|
2963
2963
|
return null;
|
|
2964
|
-
const session = localStorage.getItem(this.
|
|
2964
|
+
const session = localStorage.getItem(this.BOUNDED_SESSION_STORAGE_KEY);
|
|
2965
2965
|
if (!session)
|
|
2966
2966
|
return null;
|
|
2967
2967
|
const sessionObj = JSON.parse(session);
|
|
@@ -2985,7 +2985,7 @@ class WebSessionManager {
|
|
|
2985
2985
|
// Persist the ROTATED refresh token — the old one is now
|
|
2986
2986
|
// single-use spent; reusing it would revoke the family.
|
|
2987
2987
|
refreshed.refreshToken);
|
|
2988
|
-
const newSession = localStorage.getItem(this.
|
|
2988
|
+
const newSession = localStorage.getItem(this.BOUNDED_SESSION_STORAGE_KEY);
|
|
2989
2989
|
if (!newSession)
|
|
2990
2990
|
return null;
|
|
2991
2991
|
const newObj = JSON.parse(newSession);
|
|
@@ -3009,14 +3009,14 @@ class WebSessionManager {
|
|
|
3009
3009
|
static clearSession() {
|
|
3010
3010
|
if (typeof window === "undefined")
|
|
3011
3011
|
return;
|
|
3012
|
-
localStorage.removeItem(this.
|
|
3012
|
+
localStorage.removeItem(this.BOUNDED_SESSION_STORAGE_KEY);
|
|
3013
3013
|
}
|
|
3014
3014
|
/* ------------------------------------------------------------------ */
|
|
3015
3015
|
/* IS-AUTH */
|
|
3016
3016
|
/* ------------------------------------------------------------------ */
|
|
3017
3017
|
static isAuthenticated() {
|
|
3018
3018
|
// NOTE: this remains synchronous to stay backward compatible
|
|
3019
|
-
return !!localStorage.getItem(this.
|
|
3019
|
+
return !!localStorage.getItem(this.BOUNDED_SESSION_STORAGE_KEY);
|
|
3020
3020
|
}
|
|
3021
3021
|
/* ------------------------------------------------------------------ */
|
|
3022
3022
|
/* TOKEN HELPERS */
|
|
@@ -3024,13 +3024,13 @@ class WebSessionManager {
|
|
|
3024
3024
|
static getIdToken() {
|
|
3025
3025
|
if (typeof window === "undefined")
|
|
3026
3026
|
return null;
|
|
3027
|
-
const session = localStorage.getItem(this.
|
|
3027
|
+
const session = localStorage.getItem(this.BOUNDED_SESSION_STORAGE_KEY);
|
|
3028
3028
|
return session ? JSON.parse(session).idToken : null;
|
|
3029
3029
|
}
|
|
3030
3030
|
static getRefreshToken() {
|
|
3031
3031
|
if (typeof window === "undefined")
|
|
3032
3032
|
return null;
|
|
3033
|
-
const session = localStorage.getItem(this.
|
|
3033
|
+
const session = localStorage.getItem(this.BOUNDED_SESSION_STORAGE_KEY);
|
|
3034
3034
|
return session ? JSON.parse(session).refreshToken : null;
|
|
3035
3035
|
}
|
|
3036
3036
|
/** The issuer base that minted this session (for routing silent refresh). */
|
|
@@ -3038,7 +3038,7 @@ class WebSessionManager {
|
|
|
3038
3038
|
var _a;
|
|
3039
3039
|
if (typeof window === "undefined")
|
|
3040
3040
|
return null;
|
|
3041
|
-
const session = localStorage.getItem(this.
|
|
3041
|
+
const session = localStorage.getItem(this.BOUNDED_SESSION_STORAGE_KEY);
|
|
3042
3042
|
return session ? ((_a = JSON.parse(session).issuer) !== null && _a !== void 0 ? _a : null) : null;
|
|
3043
3043
|
}
|
|
3044
3044
|
/* ------------------------------------------------------------------ */
|
|
@@ -3048,7 +3048,7 @@ class WebSessionManager {
|
|
|
3048
3048
|
var _a;
|
|
3049
3049
|
if (typeof window === "undefined")
|
|
3050
3050
|
return;
|
|
3051
|
-
const session = localStorage.getItem(this.
|
|
3051
|
+
const session = localStorage.getItem(this.BOUNDED_SESSION_STORAGE_KEY);
|
|
3052
3052
|
if (!session)
|
|
3053
3053
|
return;
|
|
3054
3054
|
const sessionObj = JSON.parse(session);
|
|
@@ -3065,10 +3065,10 @@ class WebSessionManager {
|
|
|
3065
3065
|
sessionObj.refreshToken = refreshToken;
|
|
3066
3066
|
}
|
|
3067
3067
|
(_a = sessionObj.appId) !== null && _a !== void 0 ? _a : (sessionObj.appId = config.appId);
|
|
3068
|
-
localStorage.setItem(this.
|
|
3068
|
+
localStorage.setItem(this.BOUNDED_SESSION_STORAGE_KEY, JSON.stringify(sessionObj));
|
|
3069
3069
|
}
|
|
3070
3070
|
}
|
|
3071
|
-
WebSessionManager.
|
|
3071
|
+
WebSessionManager.BOUNDED_SESSION_STORAGE_KEY = "bounded_session_storage";
|
|
3072
3072
|
|
|
3073
3073
|
let _config = null;
|
|
3074
3074
|
class ReactNativeSessionManager {
|
|
@@ -3161,7 +3161,7 @@ class ReactNativeSessionManager {
|
|
|
3161
3161
|
// Issuer base for silent refresh (email overrides w/ humanAuthApiUrl; wallet/
|
|
3162
3162
|
// guest default to authApiUrl). See WebSessionManager for the rationale.
|
|
3163
3163
|
const sessionIssuer = (issuer || config.authApiUrl || "").replace(/\/$/, "");
|
|
3164
|
-
this.getStorage().setItem(this.
|
|
3164
|
+
this.getStorage().setItem(this.BOUNDED_SESSION_STORAGE_KEY, JSON.stringify(Object.assign({ address,
|
|
3165
3165
|
accessToken,
|
|
3166
3166
|
idToken,
|
|
3167
3167
|
refreshToken, appId: currentAppId }, (sessionIssuer ? { issuer: sessionIssuer } : {}))));
|
|
@@ -3170,7 +3170,7 @@ class ReactNativeSessionManager {
|
|
|
3170
3170
|
/* GET */
|
|
3171
3171
|
/* ------------------------------------------------------------------ */
|
|
3172
3172
|
static async getSession() {
|
|
3173
|
-
const session = this.getStorage().getItem(this.
|
|
3173
|
+
const session = this.getStorage().getItem(this.BOUNDED_SESSION_STORAGE_KEY);
|
|
3174
3174
|
if (!session)
|
|
3175
3175
|
return null;
|
|
3176
3176
|
const sessionObj = JSON.parse(session);
|
|
@@ -3191,7 +3191,7 @@ class ReactNativeSessionManager {
|
|
|
3191
3191
|
const refreshed = await refreshSession(refreshToken, sessionObj.issuer);
|
|
3192
3192
|
if ((refreshed === null || refreshed === void 0 ? void 0 : refreshed.idToken) && (refreshed === null || refreshed === void 0 ? void 0 : refreshed.accessToken)) {
|
|
3193
3193
|
await this.updateIdTokenAndAccessToken(refreshed.idToken, refreshed.accessToken, refreshed.refreshToken);
|
|
3194
|
-
const newSession = this.getStorage().getItem(this.
|
|
3194
|
+
const newSession = this.getStorage().getItem(this.BOUNDED_SESSION_STORAGE_KEY);
|
|
3195
3195
|
if (!newSession)
|
|
3196
3196
|
return null;
|
|
3197
3197
|
const newObj = JSON.parse(newSession);
|
|
@@ -3213,20 +3213,20 @@ class ReactNativeSessionManager {
|
|
|
3213
3213
|
/* CLEAR */
|
|
3214
3214
|
/* ------------------------------------------------------------------ */
|
|
3215
3215
|
static clearSession() {
|
|
3216
|
-
this.getStorage().removeItem(this.
|
|
3216
|
+
this.getStorage().removeItem(this.BOUNDED_SESSION_STORAGE_KEY);
|
|
3217
3217
|
}
|
|
3218
3218
|
/* ------------------------------------------------------------------ */
|
|
3219
3219
|
/* IS-AUTH */
|
|
3220
3220
|
/* ------------------------------------------------------------------ */
|
|
3221
3221
|
static isAuthenticated() {
|
|
3222
|
-
return !!this.getStorage().getItem(this.
|
|
3222
|
+
return !!this.getStorage().getItem(this.BOUNDED_SESSION_STORAGE_KEY);
|
|
3223
3223
|
}
|
|
3224
3224
|
/* ------------------------------------------------------------------ */
|
|
3225
3225
|
/* TOKEN HELPERS */
|
|
3226
3226
|
/* ------------------------------------------------------------------ */
|
|
3227
3227
|
static getIdToken() {
|
|
3228
3228
|
try {
|
|
3229
|
-
const session = this.getStorage().getItem(this.
|
|
3229
|
+
const session = this.getStorage().getItem(this.BOUNDED_SESSION_STORAGE_KEY);
|
|
3230
3230
|
return session ? JSON.parse(session).idToken : null;
|
|
3231
3231
|
}
|
|
3232
3232
|
catch (_a) {
|
|
@@ -3237,7 +3237,7 @@ class ReactNativeSessionManager {
|
|
|
3237
3237
|
static getIssuer() {
|
|
3238
3238
|
var _a;
|
|
3239
3239
|
try {
|
|
3240
|
-
const session = this.getStorage().getItem(this.
|
|
3240
|
+
const session = this.getStorage().getItem(this.BOUNDED_SESSION_STORAGE_KEY);
|
|
3241
3241
|
return session ? ((_a = JSON.parse(session).issuer) !== null && _a !== void 0 ? _a : null) : null;
|
|
3242
3242
|
}
|
|
3243
3243
|
catch (_b) {
|
|
@@ -3246,7 +3246,7 @@ class ReactNativeSessionManager {
|
|
|
3246
3246
|
}
|
|
3247
3247
|
static getRefreshToken() {
|
|
3248
3248
|
try {
|
|
3249
|
-
const session = this.getStorage().getItem(this.
|
|
3249
|
+
const session = this.getStorage().getItem(this.BOUNDED_SESSION_STORAGE_KEY);
|
|
3250
3250
|
return session ? JSON.parse(session).refreshToken : null;
|
|
3251
3251
|
}
|
|
3252
3252
|
catch (_a) {
|
|
@@ -3258,7 +3258,7 @@ class ReactNativeSessionManager {
|
|
|
3258
3258
|
/* ------------------------------------------------------------------ */
|
|
3259
3259
|
static async updateIdTokenAndAccessToken(idToken, accessToken, refreshToken) {
|
|
3260
3260
|
var _a;
|
|
3261
|
-
const session = this.getStorage().getItem(this.
|
|
3261
|
+
const session = this.getStorage().getItem(this.BOUNDED_SESSION_STORAGE_KEY);
|
|
3262
3262
|
if (!session)
|
|
3263
3263
|
return;
|
|
3264
3264
|
const sessionObj = JSON.parse(session);
|
|
@@ -3274,10 +3274,10 @@ class ReactNativeSessionManager {
|
|
|
3274
3274
|
sessionObj.refreshToken = refreshToken;
|
|
3275
3275
|
}
|
|
3276
3276
|
(_a = sessionObj.appId) !== null && _a !== void 0 ? _a : (sessionObj.appId = config.appId);
|
|
3277
|
-
this.getStorage().setItem(this.
|
|
3277
|
+
this.getStorage().setItem(this.BOUNDED_SESSION_STORAGE_KEY, JSON.stringify(sessionObj));
|
|
3278
3278
|
}
|
|
3279
3279
|
}
|
|
3280
|
-
ReactNativeSessionManager.
|
|
3280
|
+
ReactNativeSessionManager.BOUNDED_SESSION_STORAGE_KEY = "bounded_session_storage";
|
|
3281
3281
|
|
|
3282
3282
|
/**
|
|
3283
3283
|
* Return the active CLIENT session manager for the current runtime.
|
|
@@ -3798,9 +3798,9 @@ async function buildSetDocumentsTransaction(connection, idl, anchorProvider, pay
|
|
|
3798
3798
|
/* ENV helpers */
|
|
3799
3799
|
/* ------------------------------------------------------------------ */
|
|
3800
3800
|
// Canonical `BOUNDED_PRIVATE_KEY` (matches the CLI); legacy
|
|
3801
|
-
// `
|
|
3801
|
+
// `BOUNDED_SOLANA_KEYPAIR` still honored. Only consulted when no explicit
|
|
3802
3802
|
// keypair was provided (createWalletClient passes one).
|
|
3803
|
-
const ENV_KEYPAIRS = ["BOUNDED_PRIVATE_KEY", "
|
|
3803
|
+
const ENV_KEYPAIRS = ["BOUNDED_PRIVATE_KEY", "BOUNDED_SOLANA_KEYPAIR"];
|
|
3804
3804
|
function loadKeypairFromEnv() {
|
|
3805
3805
|
let secret;
|
|
3806
3806
|
let found;
|
|
@@ -3923,7 +3923,7 @@ var serverSessionManager = /*#__PURE__*/Object.freeze({
|
|
|
3923
3923
|
});
|
|
3924
3924
|
|
|
3925
3925
|
/**
|
|
3926
|
-
* Safe base64 helpers for
|
|
3926
|
+
* Safe base64 helpers for bounded-core.
|
|
3927
3927
|
*
|
|
3928
3928
|
* Uses the global atob/btoa when available (browser, RN with polyfill),
|
|
3929
3929
|
* falls back to the 'buffer' package (Node.js / SSR / RN without polyfill).
|
|
@@ -4103,7 +4103,7 @@ axiosRetry(apiClient, {
|
|
|
4103
4103
|
shouldResetTimeout: true,
|
|
4104
4104
|
onRetry: (retryCount, error, requestConfig) => {
|
|
4105
4105
|
var _a;
|
|
4106
|
-
console.warn(`[
|
|
4106
|
+
console.warn(`[bounded-sdk] retry ${retryCount} for ${(_a = requestConfig.method) === null || _a === void 0 ? void 0 : _a.toUpperCase()} ${requestConfig.url} — ${error.code || error.message}`);
|
|
4107
4107
|
},
|
|
4108
4108
|
});
|
|
4109
4109
|
const refreshInFlight = new Map();
|
|
@@ -4162,8 +4162,8 @@ async function makeApiRequest(method, urlPath, data, _overrides) {
|
|
|
4162
4162
|
: await createAuthHeader(config.isServer);
|
|
4163
4163
|
const headers = Object.assign({ "Content-Type": "application/json", "X-Public-App-Id": config.appId, "X-App-Id": config.appId }, authHeader);
|
|
4164
4164
|
if (typeof window !== "undefined" &&
|
|
4165
|
-
window.
|
|
4166
|
-
const customAppId = window.
|
|
4165
|
+
window.CUSTOM_BOUNDED_APP_ID_HEADER) {
|
|
4166
|
+
const customAppId = window.CUSTOM_BOUNDED_APP_ID_HEADER;
|
|
4167
4167
|
if (customAppId) {
|
|
4168
4168
|
headers["X-App-Id"] = customAppId;
|
|
4169
4169
|
}
|
|
@@ -4422,7 +4422,7 @@ function parseAggregateValue(result) {
|
|
|
4422
4422
|
* Count items in a collection path. Returns a numeric result.
|
|
4423
4423
|
*
|
|
4424
4424
|
* This uses the AI query engine with a count-specific prompt prefix,
|
|
4425
|
-
* so
|
|
4425
|
+
* so Bounded will generate a $count aggregation pipeline and return
|
|
4426
4426
|
* just the count rather than full documents.
|
|
4427
4427
|
*
|
|
4428
4428
|
* IMPORTANT: This only works for collections where the read policy is "true".
|
|
@@ -4947,10 +4947,10 @@ async function setMany(many, options) {
|
|
|
4947
4947
|
let documents = [];
|
|
4948
4948
|
const pathsToInvalidate = new Set();
|
|
4949
4949
|
for (const { path, document: documentWithReservedFields } of many) {
|
|
4950
|
-
// for setting, we should remove any pieces of the document that start with '
|
|
4950
|
+
// for setting, we should remove any pieces of the document that start with '_' as they are internal and shouldn't be updated. The API would block it if it is one of the reserved ones
|
|
4951
4951
|
let document = documentWithReservedFields;
|
|
4952
4952
|
if (documentWithReservedFields) {
|
|
4953
|
-
document = Object.fromEntries(Object.entries(documentWithReservedFields).filter(([key]) => !key.startsWith('
|
|
4953
|
+
document = Object.fromEntries(Object.entries(documentWithReservedFields).filter(([key]) => !key.startsWith('_')));
|
|
4954
4954
|
}
|
|
4955
4955
|
const normalizedPath = path.startsWith("/") ? path.slice(1) : path;
|
|
4956
4956
|
pathsToInvalidate.add(normalizedPath);
|
|
@@ -5074,7 +5074,7 @@ async function setMany(many, options) {
|
|
|
5074
5074
|
var _a, _b, _c, _d, _e;
|
|
5075
5075
|
// NOTE (backwards-compat revert): a program-allowlist on server-supplied
|
|
5076
5076
|
// `preInstructions` was tried here for the audit-8 SOL-drain concern, but it
|
|
5077
|
-
// broke legitimate onchain DeFi flows —
|
|
5077
|
+
// broke legitimate onchain DeFi flows — bounded routes Phoenix, Jupiter/swap,
|
|
5078
5078
|
// SPL-Token and ATA-creation instructions through standard-path preInstructions
|
|
5079
5079
|
// (see sol-helper remaining-accounts-extractor). A correct audit-8 fix must be
|
|
5080
5080
|
// DeFi-aware (e.g. block ONLY a raw System Transfer/TransferWithSeed, never a
|
|
@@ -5158,10 +5158,10 @@ async function setMany(many, options) {
|
|
|
5158
5158
|
const transaction = web3_js.VersionedTransaction.deserialize(txBytes);
|
|
5159
5159
|
// Validate the transaction before signing: ensure only allowed programs
|
|
5160
5160
|
// and no unauthorized System program instructions (e.g., SOL transfers)
|
|
5161
|
-
const
|
|
5161
|
+
const BOUNDED_PROGRAM = 'poof4b5pk1L9tmThvBmaABjcyjfhFGbMbQP5BXk2QZp';
|
|
5162
5162
|
const COMPUTE_BUDGET = 'ComputeBudget111111111111111111111111111111';
|
|
5163
5163
|
const SYSTEM_PROGRAM = '11111111111111111111111111111111';
|
|
5164
|
-
const ALLOWED_PROGRAMS = new Set([
|
|
5164
|
+
const ALLOWED_PROGRAMS = new Set([BOUNDED_PROGRAM, COMPUTE_BUDGET, SYSTEM_PROGRAM]);
|
|
5165
5165
|
// System program instruction discriminators (first 4 bytes, little-endian u32)
|
|
5166
5166
|
const SYSTEM_TRANSFER = 2; // Transfer instruction index
|
|
5167
5167
|
const SYSTEM_TRANSFER_WITH_SEED = 11;
|
|
@@ -5755,8 +5755,8 @@ async function getOrCreateConnection(appId, isServer, routePath, authTokenProvid
|
|
|
5755
5755
|
if (appId && appId !== config.appId) {
|
|
5756
5756
|
wsUrl.searchParams.append('appId', appId);
|
|
5757
5757
|
}
|
|
5758
|
-
else if (typeof window !== 'undefined' && window.
|
|
5759
|
-
wsUrl.searchParams.append('appId', window.
|
|
5758
|
+
else if (typeof window !== 'undefined' && window.CUSTOM_BOUNDED_APP_ID_HEADER) {
|
|
5759
|
+
wsUrl.searchParams.append('appId', window.CUSTOM_BOUNDED_APP_ID_HEADER);
|
|
5760
5760
|
}
|
|
5761
5761
|
else {
|
|
5762
5762
|
wsUrl.searchParams.append('appId', config.appId);
|
|
@@ -6616,7 +6616,7 @@ function serverTimestamp() {
|
|
|
6616
6616
|
// ---------------------------------------------------------------------------
|
|
6617
6617
|
// IDB helpers (lazy-loaded, non-blocking)
|
|
6618
6618
|
// ---------------------------------------------------------------------------
|
|
6619
|
-
const IDB_NAME = '
|
|
6619
|
+
const IDB_NAME = 'bounded-realtime';
|
|
6620
6620
|
const IDB_STORE = 'subscriptions';
|
|
6621
6621
|
const IDB_VERSION = 1;
|
|
6622
6622
|
let idbPromise = null;
|
|
@@ -7054,10 +7054,10 @@ class RealtimeStore {
|
|
|
7054
7054
|
const normalizedPath = path.startsWith('/') ? path.slice(1) : path;
|
|
7055
7055
|
const collectionPath = this.getCollectionPath(normalizedPath);
|
|
7056
7056
|
const optimisticDoc = Object.assign(Object.assign({ _id: normalizedPath, pathId: normalizedPath }, resolvedDoc), {
|
|
7057
|
-
// System timestamp field name
|
|
7058
|
-
//
|
|
7057
|
+
// System timestamp field name: the Bounded worker stamps the neutral
|
|
7058
|
+
// `_updatedAt`; the underscore-prefixed `_updated_at` metadata mirror.
|
|
7059
7059
|
// Match it so the optimistic doc lines up with the server's confirmation.
|
|
7060
|
-
[isBoundedNetwork() ? '_updatedAt' : '
|
|
7060
|
+
[isBoundedNetwork() ? '_updatedAt' : '_updated_at']: Date.now() });
|
|
7061
7061
|
const sub = this.findSubscriptionByPath(collectionPath);
|
|
7062
7062
|
let prevDoc = null;
|
|
7063
7063
|
if (sub) {
|