@concavejs/docstore-bun-sqlite 0.0.1-alpha.15 → 0.0.1-alpha.16

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 (2) hide show
  1. package/dist/index.js +724 -469
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1052,19 +1052,7 @@ function hexToString(hex) {
1052
1052
  const buffer = hexToArrayBuffer(hex);
1053
1053
  return new TextDecoder().decode(buffer);
1054
1054
  }
1055
- function deserializeDeveloperId(developerId) {
1056
- if (!developerId) {
1057
- return null;
1058
- }
1059
- for (const separator of [DOC_ID_SEPARATOR, LEGACY_DOC_ID_SEPARATOR]) {
1060
- const parts = developerId.split(separator);
1061
- if (parts.length === 2 && parts[0] && parts[1]) {
1062
- return { table: parts[0], internalId: parts[1] };
1063
- }
1064
- }
1065
- return null;
1066
- }
1067
- var BYTE_TO_HEX, HEX_TO_NIBBLE, DOC_ID_SEPARATOR = ":", LEGACY_DOC_ID_SEPARATOR = ";";
1055
+ var BYTE_TO_HEX, HEX_TO_NIBBLE;
1068
1056
  var init_utils = __esm(() => {
1069
1057
  BYTE_TO_HEX = [];
1070
1058
  for (let i2 = 0;i2 < 256; i2++) {
@@ -3312,7 +3300,7 @@ async function listSystemFunctions(options = {}) {
3312
3300
  const listing = filteredListings[i2];
3313
3301
  const result = analysisResults[i2];
3314
3302
  if (result.status === "rejected") {
3315
- if (!isNpmPackageError(result.reason)) {
3303
+ if (!isExpectedNonFunctionModuleLoadError(result.reason)) {
3316
3304
  console.warn(`Failed to analyze module "${listing.path}":`, result.reason);
3317
3305
  }
3318
3306
  continue;
@@ -3473,7 +3461,10 @@ async function discoverCronSpecs(options = {}) {
3473
3461
  }
3474
3462
  return cronSpecs;
3475
3463
  }
3476
- function isNpmPackageError(error) {
3464
+ function isExpectedNonFunctionModuleLoadError(error) {
3465
+ return isNpmPackageResolutionError(error) || isStubbedComponentDependencyError(error);
3466
+ }
3467
+ function isNpmPackageResolutionError(error) {
3477
3468
  if (!(error instanceof Error))
3478
3469
  return false;
3479
3470
  const causes = error.causes;
@@ -3489,6 +3480,15 @@ function isNpmPackageError(error) {
3489
3480
  return !modulePath.startsWith(".") && !modulePath.startsWith("/");
3490
3481
  });
3491
3482
  }
3483
+ function isStubbedComponentDependencyError(error) {
3484
+ if (!(error instanceof Error))
3485
+ return false;
3486
+ if (error.message.includes("could not be resolved while bundling component modules") && error.message.includes("only an error if this module is loaded at runtime")) {
3487
+ return true;
3488
+ }
3489
+ const causes = error.causes;
3490
+ return Array.isArray(causes) && causes.some((cause) => isStubbedComponentDependencyError(cause));
3491
+ }
3492
3492
  var moduleAnalysisCache, moduleLoaderApiPromise = null, unsubscribeModuleLoader = null;
3493
3493
  var init_function_introspection = __esm(() => {
3494
3494
  init_analysis();
@@ -5416,6 +5416,10 @@ function parseBoolean(value) {
5416
5416
  return;
5417
5417
  return value.toLowerCase() === "true" || value === "1";
5418
5418
  }
5419
+ function isDevEnvironment(env) {
5420
+ const environment = getEnvValue("ENVIRONMENT", env) ?? getEnvValue("CONCAVE_ENVIRONMENT", env) ?? getEnvValue("NODE_ENV", env);
5421
+ return environment === "development" || parseBoolean(getEnvValue("CONCAVE_DEV", env)) === true;
5422
+ }
5419
5423
  function parseNumber(value) {
5420
5424
  if (!value)
5421
5425
  return;
@@ -5425,8 +5429,7 @@ function parseNumber(value) {
5425
5429
  function resolveAdminAuthConfigFromEnv(env) {
5426
5430
  const token = getEnvValue("ADMIN_TOKEN", env) ?? getEnvValue("CONCAVE_ADMIN_TOKEN", env) ?? getEnvValue("CONCAVE_ADMIN_KEY", env);
5427
5431
  const allowInsecure = parseBoolean(getEnvValue("CONCAVE_ALLOW_INSECURE_ADMIN", env)) ?? parseBoolean(getEnvValue("ALLOW_INSECURE_ADMIN", env));
5428
- const environment = getEnvValue("ENVIRONMENT", env) ?? getEnvValue("CONCAVE_ENVIRONMENT", env) ?? getEnvValue("NODE_ENV", env);
5429
- const allowInsecureFromEnv = allowInsecure ?? environment === "development";
5432
+ const allowInsecureFromEnv = allowInsecure ?? isDevEnvironment(env);
5430
5433
  if (!token && !allowInsecureFromEnv) {
5431
5434
  return;
5432
5435
  }
@@ -5438,8 +5441,7 @@ function resolveAdminAuthConfigFromEnv(env) {
5438
5441
  function resolveSystemAuthConfigFromEnv(env) {
5439
5442
  const token = getEnvValue("SYSTEM_TOKEN", env) ?? getEnvValue("CONCAVE_SYSTEM_TOKEN", env) ?? getEnvValue("CONCAVE_SYSTEM_KEY", env);
5440
5443
  const allowInsecure = parseBoolean(getEnvValue("CONCAVE_ALLOW_INSECURE_SYSTEM", env)) ?? parseBoolean(getEnvValue("ALLOW_INSECURE_SYSTEM", env));
5441
- const environment = getEnvValue("ENVIRONMENT", env) ?? getEnvValue("CONCAVE_ENVIRONMENT", env) ?? getEnvValue("NODE_ENV", env);
5442
- const allowInsecureFromEnv = allowInsecure ?? environment === "development";
5444
+ const allowInsecureFromEnv = allowInsecure ?? isDevEnvironment(env);
5443
5445
  if (!token && !allowInsecureFromEnv) {
5444
5446
  return;
5445
5447
  }
@@ -5659,35 +5661,35 @@ var init_jwt = __esm(() => {
5659
5661
 
5660
5662
  // ../core/dist/auth/auth-context.js
5661
5663
  function getAuthContext() {
5662
- return authContext.getStore();
5664
+ return userIdentityContextStorage.getStore();
5663
5665
  }
5664
- function getPrincipal() {
5665
- return principalContext.getStore();
5666
+ function getResolvedAuthContext() {
5667
+ return resolvedAuthContextStorage.getStore();
5666
5668
  }
5667
- async function runWithAuth(auth, fn, principal) {
5668
- return principalContext.run(principal, () => authContext.run(auth, fn));
5669
+ async function runWithAuth(auth, fn, resolvedAuthContext) {
5670
+ return resolvedAuthContextStorage.run(resolvedAuthContext, () => userIdentityContextStorage.run(auth, fn));
5669
5671
  }
5670
- var AUTH_CONTEXT_SYMBOL, PRINCIPAL_CONTEXT_SYMBOL, globalAuthContext, authContext, principalContext;
5672
+ var AUTH_CONTEXT_SYMBOL, RESOLVED_AUTH_CONTEXT_SYMBOL, globalAuthContext, userIdentityContextStorage, resolvedAuthContextStorage;
5671
5673
  var init_auth_context = __esm(() => {
5672
5674
  init_context_storage();
5673
5675
  AUTH_CONTEXT_SYMBOL = Symbol.for("@concavejs/core/auth-context");
5674
- PRINCIPAL_CONTEXT_SYMBOL = Symbol.for("@concavejs/core/principal-context");
5676
+ RESOLVED_AUTH_CONTEXT_SYMBOL = Symbol.for("@concavejs/core/resolved-auth-context");
5675
5677
  globalAuthContext = globalThis;
5676
- authContext = globalAuthContext[AUTH_CONTEXT_SYMBOL] ?? new ContextStorage;
5677
- principalContext = globalAuthContext[PRINCIPAL_CONTEXT_SYMBOL] ?? new ContextStorage;
5678
+ userIdentityContextStorage = globalAuthContext[AUTH_CONTEXT_SYMBOL] ?? new ContextStorage;
5679
+ resolvedAuthContextStorage = globalAuthContext[RESOLVED_AUTH_CONTEXT_SYMBOL] ?? new ContextStorage;
5678
5680
  if (!globalAuthContext[AUTH_CONTEXT_SYMBOL]) {
5679
- globalAuthContext[AUTH_CONTEXT_SYMBOL] = authContext;
5681
+ globalAuthContext[AUTH_CONTEXT_SYMBOL] = userIdentityContextStorage;
5680
5682
  }
5681
- if (!globalAuthContext[PRINCIPAL_CONTEXT_SYMBOL]) {
5682
- globalAuthContext[PRINCIPAL_CONTEXT_SYMBOL] = principalContext;
5683
+ if (!globalAuthContext[RESOLVED_AUTH_CONTEXT_SYMBOL]) {
5684
+ globalAuthContext[RESOLVED_AUTH_CONTEXT_SYMBOL] = resolvedAuthContextStorage;
5683
5685
  }
5684
5686
  });
5685
5687
 
5686
- // ../core/dist/auth/principal.js
5687
- function anonymousPrincipal() {
5688
+ // ../core/dist/auth/resolved-auth-context.js
5689
+ function anonymousAuthContext() {
5688
5690
  return { kind: "none", scopes: [] };
5689
5691
  }
5690
- function userPrincipal(identity, token, tenantId) {
5692
+ function userAuthContext(identity, token, tenantId) {
5691
5693
  const email = identity.email;
5692
5694
  const subject = identity.subject;
5693
5695
  return {
@@ -5699,7 +5701,7 @@ function userPrincipal(identity, token, tenantId) {
5699
5701
  label: email ?? subject
5700
5702
  };
5701
5703
  }
5702
- function adminPrincipal(opts = {}) {
5704
+ function adminAuthContext(opts = {}) {
5703
5705
  return {
5704
5706
  kind: "admin",
5705
5707
  scopes: opts.scopes ?? ["*"],
@@ -5709,7 +5711,7 @@ function adminPrincipal(opts = {}) {
5709
5711
  label: opts.label ?? "admin"
5710
5712
  };
5711
5713
  }
5712
- function systemPrincipal(opts = {}) {
5714
+ function systemAuthContext(opts = {}) {
5713
5715
  return {
5714
5716
  kind: "system",
5715
5717
  scopes: opts.scopes ?? ["*"],
@@ -5718,48 +5720,122 @@ function systemPrincipal(opts = {}) {
5718
5720
  label: opts.label ?? "system"
5719
5721
  };
5720
5722
  }
5721
- function hasCapability(principal, capability) {
5722
- if (principal.kind === "none" || principal.kind === "user") {
5723
+ function hasCapability(authContext, capability) {
5724
+ if (authContext.kind === "none" || authContext.kind === "user") {
5723
5725
  return false;
5724
5726
  }
5725
- if (principal.scopes.includes("*")) {
5727
+ if (authContext.scopes.includes("*")) {
5726
5728
  return true;
5727
5729
  }
5728
- return principal.scopes.includes(capability);
5730
+ return authContext.scopes.includes(capability);
5729
5731
  }
5730
- function canCallInternal(principal) {
5731
- return principal.kind === "admin" || principal.kind === "system" || principal.kind === "service";
5732
+ function canCallInternal(authContext) {
5733
+ return authContext.kind === "admin" || authContext.kind === "system" || authContext.kind === "service";
5732
5734
  }
5733
- function canAccessComponents(principal) {
5734
- return principal.kind === "admin" || principal.kind === "system";
5735
+ function canAccessComponents(authContext) {
5736
+ return authContext.kind === "admin" || authContext.kind === "system";
5735
5737
  }
5736
5738
  function isAuthPrivileged(auth) {
5737
5739
  return auth?.tokenType === "Admin" || auth?.tokenType === "System";
5738
5740
  }
5739
- function legacyAuthContextToPrincipal(authContext2, tenantId) {
5740
- switch (authContext2.tokenType) {
5741
+ function resolvedAuthContextToWireAuthContext(authContext) {
5742
+ switch (authContext.kind) {
5743
+ case "admin":
5744
+ return { tokenType: "Admin", token: authContext.token, userIdentity: authContext.userIdentity };
5745
+ case "system":
5746
+ return { tokenType: "System", token: authContext.token, userIdentity: authContext.userIdentity };
5747
+ case "user":
5748
+ return { tokenType: "User", token: authContext.token, userIdentity: authContext.userIdentity };
5749
+ case "service":
5750
+ return { tokenType: "Admin", token: authContext.token, userIdentity: authContext.userIdentity };
5751
+ default:
5752
+ return { tokenType: "None" };
5753
+ }
5754
+ }
5755
+ function wireAuthContextToResolvedAuthContext(authContext, tenantId) {
5756
+ switch (authContext.tokenType) {
5741
5757
  case "Admin":
5742
- return adminPrincipal({
5743
- token: authContext2.token,
5758
+ return adminAuthContext({
5759
+ token: authContext.token,
5744
5760
  tenantId,
5745
- impersonating: authContext2.userIdentity,
5761
+ impersonating: authContext.userIdentity,
5746
5762
  label: "admin"
5747
5763
  });
5748
5764
  case "System":
5749
- return systemPrincipal({
5750
- token: authContext2.token,
5765
+ return systemAuthContext({
5766
+ token: authContext.token,
5751
5767
  tenantId,
5752
5768
  label: "system"
5753
5769
  });
5754
5770
  case "User":
5755
- if (authContext2.userIdentity) {
5756
- return userPrincipal(authContext2.userIdentity, authContext2.token, tenantId);
5771
+ if (authContext.userIdentity) {
5772
+ return userAuthContext(authContext.userIdentity, authContext.token, tenantId);
5757
5773
  }
5758
- return anonymousPrincipal();
5774
+ return anonymousAuthContext();
5759
5775
  default:
5760
- return anonymousPrincipal();
5776
+ return anonymousAuthContext();
5777
+ }
5778
+ }
5779
+
5780
+ // ../core/dist/auth/execution-auth.js
5781
+ function isResolvedAuthContext(value) {
5782
+ return value !== null && typeof value === "object" && "kind" in value && "scopes" in value && !("tokenType" in value);
5783
+ }
5784
+ function isWireAuthContext(value) {
5785
+ if (value === null || typeof value !== "object" || !("tokenType" in value)) {
5786
+ return false;
5787
+ }
5788
+ const tokenType = value.tokenType;
5789
+ return tokenType === "Admin" || tokenType === "System" || tokenType === "User" || tokenType === "None";
5790
+ }
5791
+ function resolveExecutionAuth(auth, tenantId) {
5792
+ if (isResolvedAuthContext(auth)) {
5793
+ return {
5794
+ authContext: auth,
5795
+ userIdentity: auth.userIdentity,
5796
+ wireAuthContext: resolvedAuthContextToWireAuthContext(auth),
5797
+ executorAuth: resolvedAuthContextToWireAuthContext(auth)
5798
+ };
5799
+ }
5800
+ if (isWireAuthContext(auth)) {
5801
+ const wireAuthContext = normalizeWireAuthContext(auth);
5802
+ return {
5803
+ authContext: wireAuthContextToResolvedAuthContext(wireAuthContext, tenantId),
5804
+ userIdentity: wireAuthContext.userIdentity,
5805
+ wireAuthContext,
5806
+ executorAuth: wireAuthContext
5807
+ };
5808
+ }
5809
+ if (auth) {
5810
+ return {
5811
+ authContext: userAuthContext(auth, undefined, tenantId),
5812
+ userIdentity: auth,
5813
+ executorAuth: auth
5814
+ };
5761
5815
  }
5816
+ return {
5817
+ authContext: anonymousAuthContext(),
5818
+ wireAuthContext: { tokenType: "None" },
5819
+ executorAuth: undefined
5820
+ };
5762
5821
  }
5822
+ function normalizeWireAuthContext(auth) {
5823
+ if (auth.tokenType !== "User" || auth.userIdentity || !auth.token) {
5824
+ return auth;
5825
+ }
5826
+ const userIdentity = identityFromTrustedToken(auth.token);
5827
+ if (!userIdentity) {
5828
+ return auth;
5829
+ }
5830
+ return {
5831
+ ...auth,
5832
+ userIdentity
5833
+ };
5834
+ }
5835
+ var init_execution_auth = __esm(() => {
5836
+ init_jwt();
5837
+ init_auth_context();
5838
+ });
5763
5839
 
5764
5840
  // ../core/dist/auth/auth-resolver.js
5765
5841
  function isLikelyJwt(token) {
@@ -5810,10 +5886,10 @@ class DefaultAuthResolver {
5810
5886
  const token = request.token;
5811
5887
  const tenantId = request.tenantId ?? this.config.tenantId;
5812
5888
  if (!token && hint === "auto") {
5813
- return { principal: anonymousPrincipal() };
5889
+ return { authContext: anonymousAuthContext() };
5814
5890
  }
5815
5891
  if (hint === "None") {
5816
- return { principal: anonymousPrincipal() };
5892
+ return { authContext: anonymousAuthContext() };
5817
5893
  }
5818
5894
  if (hint === "Admin") {
5819
5895
  return this.resolveAdmin(token, request.impersonating, tenantId);
@@ -5836,7 +5912,7 @@ class DefaultAuthResolver {
5836
5912
  if (token) {
5837
5913
  return this.resolveUser(token, tenantId);
5838
5914
  }
5839
- return { principal: anonymousPrincipal() };
5915
+ return { authContext: anonymousAuthContext() };
5840
5916
  }
5841
5917
  isInsecureAdminFallbackEnabled() {
5842
5918
  if (this.config.allowInsecure) {
@@ -5856,13 +5932,13 @@ class DefaultAuthResolver {
5856
5932
  return scoped;
5857
5933
  }
5858
5934
  this.assertAdminToken(token);
5859
- const principal = adminPrincipal({
5935
+ const authContext = adminAuthContext({
5860
5936
  token,
5861
5937
  tenantId,
5862
5938
  impersonating,
5863
5939
  label: "admin"
5864
5940
  });
5865
- return { principal, userIdentity: impersonating };
5941
+ return { authContext, userIdentity: impersonating };
5866
5942
  }
5867
5943
  async resolveSystem(token, impersonating, tenantId) {
5868
5944
  const scoped = await this.tryResolveScopedManagementJwt(token, "System", tenantId, impersonating);
@@ -5870,16 +5946,16 @@ class DefaultAuthResolver {
5870
5946
  return scoped;
5871
5947
  }
5872
5948
  this.assertSystemToken(token);
5873
- const principal = systemPrincipal({
5949
+ const authContext = systemAuthContext({
5874
5950
  token,
5875
5951
  tenantId,
5876
5952
  label: "system"
5877
5953
  });
5878
- return { principal, userIdentity: impersonating };
5954
+ return { authContext, userIdentity: impersonating };
5879
5955
  }
5880
5956
  async resolveUser(token, tenantId) {
5881
5957
  if (!token) {
5882
- return { principal: anonymousPrincipal() };
5958
+ return { authContext: anonymousAuthContext() };
5883
5959
  }
5884
5960
  const providers = this.config.jwtProviders;
5885
5961
  if (providers && providers.length > 0) {
@@ -5887,8 +5963,8 @@ class DefaultAuthResolver {
5887
5963
  for (const providerConfig of providers) {
5888
5964
  try {
5889
5965
  const identity2 = await verifyJwtAndGetIdentity(token, providerConfig);
5890
- const principal2 = userPrincipal(identity2, token, tenantId);
5891
- return { principal: principal2, userIdentity: identity2 };
5966
+ const authContext2 = userAuthContext(identity2, token, tenantId);
5967
+ return { authContext: authContext2, userIdentity: identity2 };
5892
5968
  } catch (error) {
5893
5969
  errors2.push(error instanceof Error ? error : new Error(String(error)));
5894
5970
  }
@@ -5896,8 +5972,8 @@ class DefaultAuthResolver {
5896
5972
  if (this.config.jwtConfig) {
5897
5973
  try {
5898
5974
  const identity2 = await verifyJwtAndGetIdentity(token, this.config.jwtConfig);
5899
- const principal2 = userPrincipal(identity2, token, tenantId);
5900
- return { principal: principal2, userIdentity: identity2 };
5975
+ const authContext2 = userAuthContext(identity2, token, tenantId);
5976
+ return { authContext: authContext2, userIdentity: identity2 };
5901
5977
  } catch (error) {
5902
5978
  errors2.push(error instanceof Error ? error : new Error(String(error)));
5903
5979
  }
@@ -5906,8 +5982,8 @@ class DefaultAuthResolver {
5906
5982
  throw new JWTValidationError("INVALID_TOKEN", `JWT verification failed for all providers: ${messages}`);
5907
5983
  }
5908
5984
  const identity = await verifyJwtAndGetIdentity(token, this.config.jwtConfig);
5909
- const principal = userPrincipal(identity, token, tenantId);
5910
- return { principal, userIdentity: identity };
5985
+ const authContext = userAuthContext(identity, token, tenantId);
5986
+ return { authContext, userIdentity: identity };
5911
5987
  }
5912
5988
  isAdminToken(token) {
5913
5989
  return !!this.config.adminAuth?.token && token === this.config.adminAuth.token;
@@ -6018,24 +6094,24 @@ class DefaultAuthResolver {
6018
6094
  }
6019
6095
  }
6020
6096
  const label = readStringClaim(claims, cfg.labelClaim ?? "email") ?? readStringClaim(claims, "sub") ?? undefined;
6021
- const principalTenantId = tokenTenantId ?? tenantId;
6097
+ const authContextTenantId = tokenTenantId ?? tenantId;
6022
6098
  if (expectedType === "Admin") {
6023
- const principal2 = adminPrincipal({
6099
+ const authContext2 = adminAuthContext({
6024
6100
  token,
6025
- tenantId: principalTenantId,
6101
+ tenantId: authContextTenantId,
6026
6102
  scopes: effectiveScopes,
6027
6103
  impersonating,
6028
6104
  label
6029
6105
  });
6030
- return { principal: principal2, userIdentity: impersonating };
6106
+ return { authContext: authContext2, userIdentity: impersonating };
6031
6107
  }
6032
- const principal = systemPrincipal({
6108
+ const authContext = systemAuthContext({
6033
6109
  token,
6034
- tenantId: principalTenantId,
6110
+ tenantId: authContextTenantId,
6035
6111
  scopes: effectiveScopes,
6036
6112
  label
6037
6113
  });
6038
- return { principal, userIdentity: impersonating };
6114
+ return { authContext, userIdentity: impersonating };
6039
6115
  }
6040
6116
  }
6041
6117
 
@@ -6187,44 +6263,44 @@ var init_auth_resolver = __esm(() => {
6187
6263
 
6188
6264
  // ../core/dist/auth/authorization-policy.js
6189
6265
  class DefaultAuthorizationPolicy {
6190
- authorize(principal, action) {
6266
+ authorize(authContext, action) {
6191
6267
  switch (action.kind) {
6192
6268
  case "call_function":
6193
- return this.authorizeCallFunction(principal, action);
6269
+ return this.authorizeCallFunction(authContext, action);
6194
6270
  case "call_system_function":
6195
- return this.authorizeSystemFunction(principal, action);
6271
+ return this.authorizeSystemFunction(authContext, action);
6196
6272
  case "access_component":
6197
- return this.authorizeComponentAccess(principal, action);
6273
+ return this.authorizeComponentAccess(authContext, action);
6198
6274
  case "management_operation":
6199
- return this.authorizeManagementOp(principal, action);
6275
+ return this.authorizeManagementOp(authContext, action);
6200
6276
  case "custom":
6201
6277
  return deny(`Custom action '${action.name}' not handled by default policy`);
6202
6278
  }
6203
6279
  }
6204
- authorizeCallFunction(principal, action) {
6205
- if (action.isInternal && !canCallInternal(principal)) {
6280
+ authorizeCallFunction(authContext, action) {
6281
+ if (action.isInternal && !canCallInternal(authContext)) {
6206
6282
  return deny("Internal functions require admin, system, or service authentication", "FORBIDDEN_INTERNAL");
6207
6283
  }
6208
- if (action.componentPath && !canAccessComponents(principal)) {
6284
+ if (action.componentPath && !canAccessComponents(authContext)) {
6209
6285
  return deny("Component-scoped function calls require admin or system authentication", "FORBIDDEN_COMPONENT");
6210
6286
  }
6211
6287
  return ALLOWED;
6212
6288
  }
6213
- authorizeSystemFunction(principal, action) {
6214
- if (!canCallInternal(principal)) {
6289
+ authorizeSystemFunction(authContext, action) {
6290
+ if (!canCallInternal(authContext)) {
6215
6291
  return deny(`System function '${action.functionName}' requires admin, system, or service authentication`, "FORBIDDEN_SYSTEM");
6216
6292
  }
6217
6293
  return ALLOWED;
6218
6294
  }
6219
- authorizeComponentAccess(principal, _action) {
6220
- if (!canAccessComponents(principal)) {
6295
+ authorizeComponentAccess(authContext, _action) {
6296
+ if (!canAccessComponents(authContext)) {
6221
6297
  return deny("Component access requires admin or system authentication", "FORBIDDEN_COMPONENT");
6222
6298
  }
6223
6299
  return ALLOWED;
6224
6300
  }
6225
- authorizeManagementOp(principal, action) {
6226
- if (!hasCapability(principal, action.capability)) {
6227
- return deny(`Principal lacks required capability '${action.capability}'` + (action.resource ? ` for resource '${action.resource}'` : ""), "FORBIDDEN_CAPABILITY");
6301
+ authorizeManagementOp(authContext, action) {
6302
+ if (!hasCapability(authContext, action.capability)) {
6303
+ return deny(`ResolvedAuthContext lacks required capability '${action.capability}'` + (action.resource ? ` for resource '${action.resource}'` : ""), "FORBIDDEN_CAPABILITY");
6228
6304
  }
6229
6305
  return ALLOWED;
6230
6306
  }
@@ -6232,8 +6308,8 @@ class DefaultAuthorizationPolicy {
6232
6308
  function deny(reason, code2) {
6233
6309
  return { allowed: false, reason, code: code2 };
6234
6310
  }
6235
- function requireAuthorization(principal, action, policy = defaultAuthorizationPolicy) {
6236
- const decision = policy.authorize(principal, action);
6311
+ function requireAuthorization(authContext, action, policy = defaultAuthorizationPolicy) {
6312
+ const decision = policy.authorize(authContext, action);
6237
6313
  if (!decision.allowed) {
6238
6314
  const err = new Error(decision.reason);
6239
6315
  err.code = decision.code ?? "FORBIDDEN";
@@ -6256,6 +6332,7 @@ var init_auth_config_service = __esm(() => {
6256
6332
  var init_auth = __esm(() => {
6257
6333
  init_jwt();
6258
6334
  init_auth_context();
6335
+ init_execution_auth();
6259
6336
  init_auth_resolver();
6260
6337
  init_authorization_policy();
6261
6338
  init_auth_config_service();
@@ -6354,6 +6431,7 @@ function createTableRegistrySnapshot(tables, partial) {
6354
6431
  fullName: table.fullName,
6355
6432
  isSystem: table.isSystem,
6356
6433
  visibility: table.visibility,
6434
+ state: table.state,
6357
6435
  createdAt: table.createdAt
6358
6436
  })).sort((a, b) => a.tableNumber - b.tableNumber);
6359
6437
  const updatedAt = partial?.updatedAt ?? Date.now();
@@ -6970,11 +7048,11 @@ var init_system_tables = __esm(() => {
6970
7048
 
6971
7049
  // ../core/dist/system/internal.js
6972
7050
  function requireSystemCapability(capability) {
6973
- const principal2 = getPrincipal();
6974
- if (!principal2) {
7051
+ const authContext = getResolvedAuthContext();
7052
+ if (!authContext) {
6975
7053
  throw new Error("System functions require authentication context");
6976
7054
  }
6977
- requireAuthorization(principal2, { kind: "management_operation", capability });
7055
+ requireAuthorization(authContext, { kind: "management_operation", capability });
6978
7056
  }
6979
7057
  function createSystemFunctions(deps) {
6980
7058
  const { query, mutation } = deps;
@@ -8328,8 +8406,8 @@ Path: ${formatPath(path)}
8328
8406
  Value: ${formatValue(value)}
8329
8407
  Validator: v.id("${validator2.tableName}")`);
8330
8408
  }
8331
- const tableName2 = tableNameFromConvexId(value, options);
8332
- if (!tableName2 || !isMatchingValidatorTable(tableName2, validator2.tableName, options.componentPath)) {
8409
+ const tableName = tableNameFromConvexId(value, options);
8410
+ if (!tableName || !isMatchingValidatorTable(tableName, validator2.tableName, options.componentPath)) {
8333
8411
  throw new Error(`Value does not match validator.
8334
8412
  Path: ${formatPath(path)}
8335
8413
  Value: ${formatValue(value)}
@@ -8337,14 +8415,10 @@ Validator: v.id("${validator2.tableName}")`);
8337
8415
  }
8338
8416
  return;
8339
8417
  }
8340
- const tableName = tableNameFromId(value);
8341
- if (!tableName || !isMatchingValidatorTable(tableName, validator2.tableName, options.componentPath)) {
8342
- throw new Error(`Value does not match validator.
8418
+ throw new Error(`Value does not match validator.
8343
8419
  Path: ${formatPath(path)}
8344
8420
  Value: ${formatValue(value)}
8345
8421
  Validator: v.id("${validator2.tableName}")`);
8346
- }
8347
- return;
8348
8422
  }
8349
8423
  case "array": {
8350
8424
  if (!Array.isArray(value)) {
@@ -8413,13 +8487,6 @@ Validator: v.object({...})`);
8413
8487
  }
8414
8488
  }
8415
8489
  }
8416
- function tableNameFromId(id) {
8417
- const parts = deserializeDeveloperId(id);
8418
- if (!parts) {
8419
- return null;
8420
- }
8421
- return hexToString(parts.table);
8422
- }
8423
8490
  function tableNameFromConvexId(id, options) {
8424
8491
  try {
8425
8492
  const decoded = decodeDocumentId(id);
@@ -8535,7 +8602,6 @@ function isSimpleObject2(value) {
8535
8602
  }
8536
8603
  var ValidatorError, referencedTableNamesCache;
8537
8604
  var init_validator2 = __esm(() => {
8538
- init_utils();
8539
8605
  init_interface2();
8540
8606
  init_module_loader();
8541
8607
  init_id_codec();
@@ -8632,60 +8698,7 @@ var GLOBALS_TABLE_SCHEMA = `
8632
8698
  `;
8633
8699
  // ../core/dist/abstractions/runtime-services.js
8634
8700
  function resolveRuntimeServices(services) {
8635
- if (isResolvedRuntimeServices(services)) {
8636
- return services;
8637
- }
8638
- const storageCapabilities = resolveStorageCapabilities(services);
8639
- return {
8640
- ...services,
8641
- blobstore: storageCapabilities.blobs?.store,
8642
- searchstore: storageCapabilities.search,
8643
- vecstore: storageCapabilities.vector,
8644
- storageCapabilities
8645
- };
8646
- }
8647
- function isResolvedRuntimeServices(services) {
8648
- return "storageCapabilities" in services;
8649
- }
8650
- function resolveStorageCapabilities(services) {
8651
- const blobCapability = resolveBlobCapability(services.capabilities?.blobs);
8652
- const searchCapability = resolveSearchCapability(services.capabilities?.search, services.docstore);
8653
- const vectorCapability = resolveVectorCapability(services.capabilities?.vector, services.docstore);
8654
- return {
8655
- ...blobCapability ? { blobs: blobCapability } : {},
8656
- ...searchCapability ? { search: searchCapability } : {},
8657
- ...vectorCapability ? { vector: vectorCapability } : {}
8658
- };
8659
- }
8660
- function resolveBlobCapability(capability) {
8661
- if (!capability) {
8662
- return;
8663
- }
8664
- if (!isBlobCapabilityObject(capability)) {
8665
- throw new Error("storage.blobstore must be false or an object with a BlobStore in storage.blobstore.store");
8666
- }
8667
- if (capability.consistency !== "atomic" && capability.consistency !== "eventual") {
8668
- throw new Error('storage.blobstore.consistency must be "atomic" or "eventual"');
8669
- }
8670
- return {
8671
- store: capability.store,
8672
- consistency: capability.consistency
8673
- };
8674
- }
8675
- function isBlobCapabilityObject(capability) {
8676
- return typeof capability === "object" && capability !== null && typeof capability.store?.store === "function" && typeof capability.store?.get === "function" && typeof capability.store?.delete === "function" && typeof capability.store?.getUrl === "function";
8677
- }
8678
- function resolveSearchCapability(capability, _docstore) {
8679
- if (capability === false) {
8680
- return;
8681
- }
8682
- return capability;
8683
- }
8684
- function resolveVectorCapability(capability, _docstore) {
8685
- if (capability === false) {
8686
- return;
8687
- }
8688
- return capability;
8701
+ return services;
8689
8702
  }
8690
8703
  // ../core/dist/abstractions/storage-spec.js
8691
8704
  var CAPABILITY_MAP_KEYS = new Set([
@@ -8694,10 +8707,7 @@ var CAPABILITY_MAP_KEYS = new Set([
8694
8707
  "search",
8695
8708
  "vecstore",
8696
8709
  "transaction",
8697
- "close",
8698
- "documents",
8699
- "blobs",
8700
- "vector"
8710
+ "close"
8701
8711
  ]);
8702
8712
 
8703
8713
  // ../core/dist/index.js
@@ -8848,6 +8858,7 @@ init_interface();
8848
8858
  // ../core/dist/queryengine/developer-id.js
8849
8859
  init_utils();
8850
8860
  init_id_codec();
8861
+ var LEGACY_INTERNAL_DOCUMENT_ID_RE = /^([0-9a-fA-F]+):([0-9a-fA-F]{32})$/;
8851
8862
  function parseDeveloperId(developerId) {
8852
8863
  if (isValidDocumentId(developerId)) {
8853
8864
  try {
@@ -8857,13 +8868,11 @@ function parseDeveloperId(developerId) {
8857
8868
  internalId: internalIdToHex(decoded.internalId),
8858
8869
  tableNumber: decoded.tableNumber
8859
8870
  };
8860
- } catch {}
8861
- }
8862
- const parts = deserializeDeveloperId(developerId);
8863
- if (!parts) {
8864
- return null;
8871
+ } catch {
8872
+ return null;
8873
+ }
8865
8874
  }
8866
- return { table: parts.table, internalId: parts.internalId };
8875
+ return parseLegacyInternalDocumentId(developerId);
8867
8876
  }
8868
8877
  async function parseDeveloperIdWithTableRegistry(developerId, tableRegistry) {
8869
8878
  if (isValidDocumentId(developerId)) {
@@ -8897,6 +8906,20 @@ function parseStorageId(storageId) {
8897
8906
  }
8898
8907
  return null;
8899
8908
  }
8909
+ function parseLegacyInternalDocumentId(developerId) {
8910
+ const match = LEGACY_INTERNAL_DOCUMENT_ID_RE.exec(developerId);
8911
+ if (!match) {
8912
+ return null;
8913
+ }
8914
+ const table = match[1].toLowerCase();
8915
+ if (table.length === 0 || table.length % 2 !== 0) {
8916
+ return null;
8917
+ }
8918
+ return {
8919
+ table,
8920
+ internalId: match[2].toLowerCase()
8921
+ };
8922
+ }
8900
8923
  function isTablePlaceholder(table) {
8901
8924
  return table.startsWith("#");
8902
8925
  }
@@ -9027,6 +9050,123 @@ class UncommittedWrites {
9027
9050
  }
9028
9051
  }
9029
9052
 
9053
+ // ../core/dist/transactor/occ-transaction.js
9054
+ init_udf_trace();
9055
+
9056
+ // ../core/dist/limits/transaction-headroom.js
9057
+ init_values();
9058
+ var MEBIBYTE = 1024 * 1024;
9059
+ var TRANSACTION_HEADROOM_LIMITS = {
9060
+ bytesRead: 16 * MEBIBYTE,
9061
+ bytesWritten: 16 * MEBIBYTE,
9062
+ databaseQueries: 4096,
9063
+ documentsRead: 32000,
9064
+ documentsWritten: 16000,
9065
+ functionsScheduled: 1000,
9066
+ scheduledFunctionArgsBytes: 16 * MEBIBYTE
9067
+ };
9068
+ var encoder = new TextEncoder;
9069
+ function remaining(limit, used) {
9070
+ return Math.max(0, limit - used);
9071
+ }
9072
+ function estimateConvexValueBytes(value) {
9073
+ const json = JSON.stringify(convexToJson(value));
9074
+ return encoder.encode(json).byteLength;
9075
+ }
9076
+
9077
+ class TransactionHeadroomTracker {
9078
+ bytesRead = 0;
9079
+ documentsRead = 0;
9080
+ databaseQueries = 0;
9081
+ functionsScheduled = 0;
9082
+ scheduledFunctionArgsBytes = 0;
9083
+ bytesWritten = 0;
9084
+ writtenDocuments = new Map;
9085
+ recordDatabaseQuery(count = 1) {
9086
+ this.databaseQueries += count;
9087
+ }
9088
+ recordRead(value) {
9089
+ this.documentsRead += 1;
9090
+ this.bytesRead += estimateConvexValueBytes(value);
9091
+ }
9092
+ recordReads(values) {
9093
+ for (const value of values) {
9094
+ this.recordRead(value);
9095
+ }
9096
+ }
9097
+ recordScheduledFunction(args) {
9098
+ this.functionsScheduled += 1;
9099
+ this.scheduledFunctionArgsBytes += estimateConvexValueBytes(args);
9100
+ }
9101
+ trackWrittenDocument(documentKey, value) {
9102
+ const nextBytes = estimateConvexValueBytes(value);
9103
+ const previousBytes = this.writtenDocuments.get(documentKey);
9104
+ if (previousBytes !== undefined) {
9105
+ this.bytesWritten -= previousBytes;
9106
+ }
9107
+ this.writtenDocuments.set(documentKey, nextBytes);
9108
+ this.bytesWritten += nextBytes;
9109
+ }
9110
+ snapshot() {
9111
+ return {
9112
+ bytesRead: this.bytesRead,
9113
+ documentsRead: this.documentsRead,
9114
+ databaseQueries: this.databaseQueries,
9115
+ functionsScheduled: this.functionsScheduled,
9116
+ scheduledFunctionArgsBytes: this.scheduledFunctionArgsBytes,
9117
+ bytesWritten: this.bytesWritten,
9118
+ writtenDocuments: new Map(this.writtenDocuments)
9119
+ };
9120
+ }
9121
+ restore(snapshot) {
9122
+ this.bytesRead = snapshot.bytesRead;
9123
+ this.documentsRead = snapshot.documentsRead;
9124
+ this.databaseQueries = snapshot.databaseQueries;
9125
+ this.functionsScheduled = snapshot.functionsScheduled;
9126
+ this.scheduledFunctionArgsBytes = snapshot.scheduledFunctionArgsBytes;
9127
+ this.bytesWritten = snapshot.bytesWritten;
9128
+ this.writtenDocuments.clear();
9129
+ for (const [documentKey, bytes] of snapshot.writtenDocuments) {
9130
+ this.writtenDocuments.set(documentKey, bytes);
9131
+ }
9132
+ }
9133
+ getHeadroom() {
9134
+ return {
9135
+ bytesRead: {
9136
+ used: this.bytesRead,
9137
+ remaining: remaining(TRANSACTION_HEADROOM_LIMITS.bytesRead, this.bytesRead)
9138
+ },
9139
+ bytesWritten: {
9140
+ used: this.bytesWritten,
9141
+ remaining: remaining(TRANSACTION_HEADROOM_LIMITS.bytesWritten, this.bytesWritten)
9142
+ },
9143
+ databaseQueries: {
9144
+ used: this.databaseQueries,
9145
+ remaining: remaining(TRANSACTION_HEADROOM_LIMITS.databaseQueries, this.databaseQueries)
9146
+ },
9147
+ documentsRead: {
9148
+ used: this.documentsRead,
9149
+ remaining: remaining(TRANSACTION_HEADROOM_LIMITS.documentsRead, this.documentsRead)
9150
+ },
9151
+ documentsWritten: {
9152
+ used: this.writtenDocuments.size,
9153
+ remaining: remaining(TRANSACTION_HEADROOM_LIMITS.documentsWritten, this.writtenDocuments.size)
9154
+ },
9155
+ functionsScheduled: {
9156
+ used: this.functionsScheduled,
9157
+ remaining: remaining(TRANSACTION_HEADROOM_LIMITS.functionsScheduled, this.functionsScheduled)
9158
+ },
9159
+ scheduledFunctionArgsBytes: {
9160
+ used: this.scheduledFunctionArgsBytes,
9161
+ remaining: remaining(TRANSACTION_HEADROOM_LIMITS.scheduledFunctionArgsBytes, this.scheduledFunctionArgsBytes)
9162
+ }
9163
+ };
9164
+ }
9165
+ }
9166
+
9167
+ // ../core/dist/transactor/occ-commit.js
9168
+ init_udf_trace();
9169
+
9030
9170
  // ../core/dist/transactor/occ-validation.js
9031
9171
  init_interface();
9032
9172
  init_interface();
@@ -9064,7 +9204,7 @@ function createDocumentReadValidationMap(docstore, documentReads) {
9064
9204
  if (pendingIds.length === 0) {
9065
9205
  return;
9066
9206
  }
9067
- return docstore.get_many(pendingIds);
9207
+ return docstore.getMany(pendingIds);
9068
9208
  }
9069
9209
  async function validateDocumentRead(docstore, key, readVersion, currentDocsPromise) {
9070
9210
  const parsedId = parseDocumentIdKey(key);
@@ -9121,7 +9261,7 @@ async function validateIndexRangeRead(docstore, indexId, startKey, endKey, readT
9121
9261
  const interval = { start: startKey, end: endKey };
9122
9262
  const validationReadTimestamp = resolveValidationReadTimestamp(docstore, readTimestamp);
9123
9263
  const currentDocIds = new Set;
9124
- for await (const [, doc] of docstore.index_scan(encodedIndexId, encodedTableId, validationReadTimestamp, interval, Order.Asc)) {
9264
+ for await (const [, doc] of docstore.indexScan(encodedIndexId, encodedTableId, validationReadTimestamp, interval, Order.Asc)) {
9125
9265
  currentDocIds.add(documentIdKey(doc.value.id));
9126
9266
  }
9127
9267
  for (const docId of currentDocIds) {
@@ -9160,119 +9300,47 @@ function resolveValidationReadTimestamp(docstore, minimumTimestamp) {
9160
9300
  return latestKnownTimestamp > minimumTimestamp ? latestKnownTimestamp : minimumTimestamp;
9161
9301
  }
9162
9302
 
9163
- // ../core/dist/transactor/occ-transaction.js
9303
+ // ../core/dist/transactor/occ-commit.js
9164
9304
  init_commit_lock();
9165
- init_udf_trace();
9166
-
9167
- // ../core/dist/limits/transaction-headroom.js
9168
- init_values();
9169
- var MEBIBYTE = 1024 * 1024;
9170
- var TRANSACTION_HEADROOM_LIMITS = {
9171
- bytesRead: 16 * MEBIBYTE,
9172
- bytesWritten: 16 * MEBIBYTE,
9173
- databaseQueries: 4096,
9174
- documentsRead: 32000,
9175
- documentsWritten: 16000,
9176
- functionsScheduled: 1000,
9177
- scheduledFunctionArgsBytes: 16 * MEBIBYTE
9178
- };
9179
- var encoder = new TextEncoder;
9180
- function remaining(limit, used) {
9181
- return Math.max(0, limit - used);
9182
- }
9183
- function estimateConvexValueBytes(value) {
9184
- const json = JSON.stringify(convexToJson(value));
9185
- return encoder.encode(json).byteLength;
9186
- }
9187
-
9188
- class TransactionHeadroomTracker {
9189
- bytesRead = 0;
9190
- documentsRead = 0;
9191
- databaseQueries = 0;
9192
- functionsScheduled = 0;
9193
- scheduledFunctionArgsBytes = 0;
9194
- bytesWritten = 0;
9195
- writtenDocuments = new Map;
9196
- recordDatabaseQuery(count = 1) {
9197
- this.databaseQueries += count;
9198
- }
9199
- recordRead(value) {
9200
- this.documentsRead += 1;
9201
- this.bytesRead += estimateConvexValueBytes(value);
9202
- }
9203
- recordReads(values) {
9204
- for (const value of values) {
9205
- this.recordRead(value);
9305
+ async function commitOccWrites(request) {
9306
+ let committedTimestamp = 0n;
9307
+ const runCommit = async () => {
9308
+ await withTraceSpan("occ.validate_read_set", "transaction", async () => {
9309
+ await validateReadSetForCommit(request.docstore, request.readChecks, request.writtenDocKeys);
9310
+ }, {
9311
+ readCheckCount: request.readChecks.length
9312
+ });
9313
+ committedTimestamp = await request.allocateCommitTimestamp();
9314
+ addTraceEvent("occ.commit_timestamp_allocated", {
9315
+ commitTimestamp: committedTimestamp.toString()
9316
+ });
9317
+ for (const entry of request.writeEntries) {
9318
+ entry.ts = committedTimestamp;
9206
9319
  }
9207
- }
9208
- recordScheduledFunction(args) {
9209
- this.functionsScheduled += 1;
9210
- this.scheduledFunctionArgsBytes += estimateConvexValueBytes(args);
9211
- }
9212
- trackWrittenDocument(documentKey, value) {
9213
- const nextBytes = estimateConvexValueBytes(value);
9214
- const previousBytes = this.writtenDocuments.get(documentKey);
9215
- if (previousBytes !== undefined) {
9216
- this.bytesWritten -= previousBytes;
9320
+ for (const indexEntry of request.indexEntries) {
9321
+ indexEntry.ts = committedTimestamp;
9217
9322
  }
9218
- this.writtenDocuments.set(documentKey, nextBytes);
9219
- this.bytesWritten += nextBytes;
9220
- }
9221
- snapshot() {
9222
- return {
9223
- bytesRead: this.bytesRead,
9224
- documentsRead: this.documentsRead,
9225
- databaseQueries: this.databaseQueries,
9226
- functionsScheduled: this.functionsScheduled,
9227
- scheduledFunctionArgsBytes: this.scheduledFunctionArgsBytes,
9228
- bytesWritten: this.bytesWritten,
9229
- writtenDocuments: new Map(this.writtenDocuments)
9230
- };
9231
- }
9232
- restore(snapshot) {
9233
- this.bytesRead = snapshot.bytesRead;
9234
- this.documentsRead = snapshot.documentsRead;
9235
- this.databaseQueries = snapshot.databaseQueries;
9236
- this.functionsScheduled = snapshot.functionsScheduled;
9237
- this.scheduledFunctionArgsBytes = snapshot.scheduledFunctionArgsBytes;
9238
- this.bytesWritten = snapshot.bytesWritten;
9239
- this.writtenDocuments.clear();
9240
- for (const [documentKey, bytes] of snapshot.writtenDocuments) {
9241
- this.writtenDocuments.set(documentKey, bytes);
9323
+ if (request.writeEntries.length > 0 || request.indexEntries.size > 0) {
9324
+ await withTraceSpan("occ.persist_writes", "storage", async () => {
9325
+ await request.docstore.write(request.writeEntries, request.indexEntries, "Error");
9326
+ }, {
9327
+ documentCount: request.writeEntries.length,
9328
+ indexUpdateCount: request.indexEntries.size
9329
+ });
9242
9330
  }
9331
+ };
9332
+ try {
9333
+ await commitWithDerivedSync(request.docstore, { searchstore: request.searchstore, vecstore: request.vecstore }, request.writeEntries, runCommit);
9334
+ } catch (error) {
9335
+ if (error instanceof ConflictError) {
9336
+ addTraceEvent("occ.conflict", {
9337
+ message: error.message
9338
+ });
9339
+ throw error;
9340
+ }
9341
+ throw error;
9243
9342
  }
9244
- getHeadroom() {
9245
- return {
9246
- bytesRead: {
9247
- used: this.bytesRead,
9248
- remaining: remaining(TRANSACTION_HEADROOM_LIMITS.bytesRead, this.bytesRead)
9249
- },
9250
- bytesWritten: {
9251
- used: this.bytesWritten,
9252
- remaining: remaining(TRANSACTION_HEADROOM_LIMITS.bytesWritten, this.bytesWritten)
9253
- },
9254
- databaseQueries: {
9255
- used: this.databaseQueries,
9256
- remaining: remaining(TRANSACTION_HEADROOM_LIMITS.databaseQueries, this.databaseQueries)
9257
- },
9258
- documentsRead: {
9259
- used: this.documentsRead,
9260
- remaining: remaining(TRANSACTION_HEADROOM_LIMITS.documentsRead, this.documentsRead)
9261
- },
9262
- documentsWritten: {
9263
- used: this.writtenDocuments.size,
9264
- remaining: remaining(TRANSACTION_HEADROOM_LIMITS.documentsWritten, this.writtenDocuments.size)
9265
- },
9266
- functionsScheduled: {
9267
- used: this.functionsScheduled,
9268
- remaining: remaining(TRANSACTION_HEADROOM_LIMITS.functionsScheduled, this.functionsScheduled)
9269
- },
9270
- scheduledFunctionArgsBytes: {
9271
- used: this.scheduledFunctionArgsBytes,
9272
- remaining: remaining(TRANSACTION_HEADROOM_LIMITS.scheduledFunctionArgsBytes, this.scheduledFunctionArgsBytes)
9273
- }
9274
- };
9275
- }
9343
+ return committedTimestamp;
9276
9344
  }
9277
9345
 
9278
9346
  // ../core/dist/transactor/occ-transaction.js
@@ -9427,7 +9495,7 @@ class OccMutationTransaction {
9427
9495
  const requests = Array.from(this.pendingLatestFetches.values());
9428
9496
  this.pendingLatestFetches.clear();
9429
9497
  try {
9430
- const fetched = await withTraceSpan("tx.get_many_latest", "storage", () => this.docstore.get_many(requests.map((request) => request.id), this.snapshotTimestamp), { documentCount: requests.length });
9498
+ const fetched = await withTraceSpan("tx.getManyLatest", "storage", () => this.docstore.getMany(requests.map((request) => request.id), this.snapshotTimestamp), { documentCount: requests.length });
9431
9499
  for (const request of requests) {
9432
9500
  const key = documentIdKey(request.id);
9433
9501
  const latest = fetched.get(key) ?? null;
@@ -9456,7 +9524,7 @@ class OccMutationTransaction {
9456
9524
  missingIds.push(id);
9457
9525
  }
9458
9526
  if (missingIds.length > 0) {
9459
- const fetched = await withTraceSpan("tx.get_many_latest", "storage", () => this.docstore.get_many(missingIds, this.snapshotTimestamp), { documentCount: missingIds.length });
9527
+ const fetched = await withTraceSpan("tx.getManyLatest", "storage", () => this.docstore.getMany(missingIds, this.snapshotTimestamp), { documentCount: missingIds.length });
9460
9528
  for (const id of missingIds) {
9461
9529
  const key = documentIdKey(id);
9462
9530
  const latest = fetched.get(key) ?? null;
@@ -9587,43 +9655,16 @@ class OccMutationTransaction {
9587
9655
  stagedIndexCount: indexEntries.size,
9588
9656
  readCheckCount: readChecks.length
9589
9657
  });
9590
- let committedTimestamp = 0n;
9591
- const runCommit = async () => {
9592
- await withTraceSpan("occ.validate_read_set", "transaction", async () => {
9593
- await validateReadSetForCommit(this.docstore, readChecks, writtenDocKeys);
9594
- }, {
9595
- readCheckCount: readChecks.length
9596
- });
9597
- committedTimestamp = await this.allocateCommitTimestamp();
9598
- addTraceEvent("occ.commit_timestamp_allocated", {
9599
- commitTimestamp: committedTimestamp.toString()
9600
- });
9601
- for (const entry of writeEntries) {
9602
- entry.ts = committedTimestamp;
9603
- }
9604
- for (const indexEntry of indexEntries) {
9605
- indexEntry.ts = committedTimestamp;
9606
- }
9607
- if (writeEntries.length > 0 || indexEntries.size > 0) {
9608
- await withTraceSpan("occ.persist_writes", "storage", async () => {
9609
- await this.docstore.write(writeEntries, indexEntries, "Error");
9610
- }, {
9611
- documentCount: writeEntries.length,
9612
- indexUpdateCount: indexEntries.size
9613
- });
9614
- }
9615
- };
9616
- try {
9617
- await commitWithDerivedSync(this.docstore, { searchstore: this.searchstore, vecstore: this.vecstore }, writeEntries, runCommit);
9618
- } catch (error) {
9619
- if (error instanceof ConflictError) {
9620
- addTraceEvent("occ.conflict", {
9621
- message: error.message
9622
- });
9623
- throw error;
9624
- }
9625
- throw error;
9626
- }
9658
+ const committedTimestamp = await commitOccWrites({
9659
+ docstore: this.docstore,
9660
+ searchstore: this.searchstore,
9661
+ vecstore: this.vecstore,
9662
+ writeEntries,
9663
+ indexEntries,
9664
+ readChecks,
9665
+ writtenDocKeys,
9666
+ allocateCommitTimestamp: () => this.allocateCommitTimestamp()
9667
+ });
9627
9668
  setCurrentTraceSpanAttributes({
9628
9669
  committedTimestamp: committedTimestamp.toString()
9629
9670
  });
@@ -9651,6 +9692,7 @@ class SchemaService {
9651
9692
  tableCache = new Map;
9652
9693
  schemaValidator;
9653
9694
  componentPath;
9695
+ tableRegistry;
9654
9696
  runtimeMetadataSnapshot;
9655
9697
  constructor(componentPath, tableRegistry, runtimeMetadataSnapshot) {
9656
9698
  this.componentPath = componentPath;
@@ -9861,7 +9903,7 @@ class SnapshotDocAccess {
9861
9903
  missingIds.push(id);
9862
9904
  }
9863
9905
  if (missingIds.length > 0) {
9864
- const fetched = await withTraceSpan("doc_access.get_many", "storage", () => this.docstore.get_many(missingIds, snapshotTimestamp), { documentCount: missingIds.length });
9906
+ const fetched = await withTraceSpan("doc_access.getMany", "storage", () => this.docstore.getMany(missingIds, snapshotTimestamp), { documentCount: missingIds.length });
9865
9907
  for (const id of missingIds) {
9866
9908
  const docKey = documentIdKey(id);
9867
9909
  const cacheKey = `${snapshotTimestamp}:${documentIdKey(id)}`;
@@ -9907,7 +9949,7 @@ class SnapshotDocAccess {
9907
9949
  this.pendingLatestBatches.delete(snapshotTimestamp);
9908
9950
  const requests = Array.from(batch.values());
9909
9951
  try {
9910
- const results = await withTraceSpan("doc_access.get_many", "storage", () => this.docstore.get_many(requests.map((request) => request.id), snapshotTimestamp), { documentCount: requests.length });
9952
+ const results = await withTraceSpan("doc_access.getMany", "storage", () => this.docstore.getMany(requests.map((request) => request.id), snapshotTimestamp), { documentCount: requests.length });
9911
9953
  for (const request of requests) {
9912
9954
  request.resolve(results.get(documentIdKey(request.id)) ?? null);
9913
9955
  }
@@ -9928,7 +9970,7 @@ class SnapshotDocAccess {
9928
9970
  hasTransaction() {
9929
9971
  return false;
9930
9972
  }
9931
- getDocStore() {
9973
+ getIndexReader() {
9932
9974
  return this.docstore;
9933
9975
  }
9934
9976
  getWriteVersion() {
@@ -9984,7 +10026,7 @@ class TransactionalDocAccess {
9984
10026
  hasTransaction() {
9985
10027
  return true;
9986
10028
  }
9987
- getDocStore() {
10029
+ getIndexReader() {
9988
10030
  return this.docstore;
9989
10031
  }
9990
10032
  getWriteVersion() {
@@ -10175,7 +10217,7 @@ function rangeExpressionsToIndexBounds(expressions, indexFields) {
10175
10217
  }
10176
10218
  return { start, end };
10177
10219
  }
10178
- async function executeIndexQuery(docstore, tableName, indexName, indexFields, expressions, order, limit, cursor, snapshotTimestamp, onDocumentRead, options) {
10220
+ async function executeIndexQuery(indexReader, tableName, indexName, indexFields, expressions, order, limit, cursor, snapshotTimestamp, onDocumentRead, options) {
10179
10221
  return withTraceSpan("query.index.scan", "storage", async () => {
10180
10222
  const tableId = stringToHex(tableName);
10181
10223
  const indexId = stringToHex(`${tableName}:${indexName}`);
@@ -10197,8 +10239,8 @@ async function executeIndexQuery(docstore, tableName, indexName, indexFields, ex
10197
10239
  }
10198
10240
  const results = [];
10199
10241
  const scanLimit = limit !== null ? limit + 1 : Number.MAX_SAFE_INTEGER;
10200
- const bulkDocStore = docstore;
10201
- const canUseResumePushdown = resumeIndexKey !== null && typeof bulkDocStore.index_scan_rows_after_key === "function";
10242
+ const bulkIndexReader = indexReader;
10243
+ const canUseResumePushdown = resumeIndexKey !== null && typeof bulkIndexReader.indexScanRowsAfterKey === "function";
10202
10244
  const skippingNeedsInMemoryPass = cursor !== null;
10203
10245
  const pushdownLimit = limit !== null && !skippingNeedsInMemoryPass ? scanLimit : undefined;
10204
10246
  let count = 0;
@@ -10236,21 +10278,21 @@ async function executeIndexQuery(docstore, tableName, indexName, indexFields, ex
10236
10278
  addTraceEvent("query.index.scan.pushdown_resume", {
10237
10279
  resumeMode: "index_key"
10238
10280
  });
10239
- const rows = await bulkDocStore.index_scan_rows_after_key(indexId, tableId, readTimestamp, interval, indexOrder, resumeIndexKey, pushdownLimit);
10281
+ const rows = await bulkIndexReader.indexScanRowsAfterKey(indexId, tableId, readTimestamp, interval, indexOrder, resumeIndexKey, pushdownLimit);
10240
10282
  for (const [indexKey, document] of rows) {
10241
10283
  if (!processRow(indexKey, document)) {
10242
10284
  break;
10243
10285
  }
10244
10286
  }
10245
- } else if (typeof bulkDocStore.index_scan_rows === "function") {
10246
- const rows = await bulkDocStore.index_scan_rows(indexId, tableId, readTimestamp, interval, indexOrder, pushdownLimit);
10287
+ } else if (typeof bulkIndexReader.indexScanRows === "function") {
10288
+ const rows = await bulkIndexReader.indexScanRows(indexId, tableId, readTimestamp, interval, indexOrder, pushdownLimit);
10247
10289
  for (const [indexKey, document] of rows) {
10248
10290
  if (!processRow(indexKey, document)) {
10249
10291
  break;
10250
10292
  }
10251
10293
  }
10252
10294
  } else {
10253
- const generator = docstore.index_scan(indexId, tableId, readTimestamp, interval, indexOrder, pushdownLimit);
10295
+ const generator = indexReader.indexScan(indexId, tableId, readTimestamp, interval, indexOrder, pushdownLimit);
10254
10296
  for await (const [indexKey, document] of generator) {
10255
10297
  if (!processRow(indexKey, document)) {
10256
10298
  break;
@@ -10952,7 +10994,7 @@ async function executeIndexRangePlan(plan, cursor, limit, deps) {
10952
10994
  let paginationResult;
10953
10995
  let usedFallback = false;
10954
10996
  try {
10955
- const indexResult = await executeIndexQuery(deps.docStore.getDocStore(), plan.fullTableName, plan.indexDescriptor, plan.indexFields, plan.expressions, plan.order, limit, cursor, deps.context.snapshotTimestamp, observedDocuments ? (latestDoc) => {
10997
+ const indexResult = await executeIndexQuery(deps.docStore.getIndexReader(), plan.fullTableName, plan.indexDescriptor, plan.indexFields, plan.expressions, plan.order, limit, cursor, deps.context.snapshotTimestamp, observedDocuments ? (latestDoc) => {
10956
10998
  observedDocuments.set(documentIdKey(latestDoc.value.id), latestDoc);
10957
10999
  } : undefined, {
10958
11000
  bounds: { start, end }
@@ -12084,19 +12126,30 @@ function getSyscallApiProfile(id = "convex-1.0") {
12084
12126
  }
12085
12127
 
12086
12128
  // ../core/dist/kernel/syscalls/capabilities.js
12087
- var CAPABILITY_UDF_TYPES = {
12088
- databaseRead: ["query", "mutation"],
12089
- databaseWrite: ["mutation"],
12090
- nestedQuery: ["query", "mutation", "action", "httpAction"],
12091
- nestedMutation: ["mutation", "action", "httpAction"],
12092
- nestedAction: ["action", "httpAction"],
12093
- actionSearch: ["action", "httpAction"],
12094
- functionHandle: ["query", "mutation", "action", "httpAction"],
12095
- mutationScheduler: ["mutation"],
12096
- actionScheduler: ["action", "httpAction"]
12129
+ var UDF_SYSCALL_CAPABILITIES = {
12130
+ query: ["databaseRead", "nestedQuery", "functionHandle", "transactionHeadroom"],
12131
+ mutation: [
12132
+ "databaseRead",
12133
+ "databaseWrite",
12134
+ "nestedQuery",
12135
+ "nestedMutation",
12136
+ "functionHandle",
12137
+ "mutationScheduler",
12138
+ "transactionHeadroom"
12139
+ ],
12140
+ action: ["nestedQuery", "nestedMutation", "nestedAction", "actionSearch", "functionHandle", "actionScheduler"],
12141
+ httpAction: ["nestedQuery", "nestedMutation", "nestedAction", "actionSearch", "functionHandle", "actionScheduler"]
12097
12142
  };
12143
+ var NESTED_UDF_CAPABILITY = {
12144
+ query: "nestedQuery",
12145
+ mutation: "nestedMutation",
12146
+ action: "nestedAction"
12147
+ };
12148
+ function hasSyscallCapability(udfType, capability) {
12149
+ return UDF_SYSCALL_CAPABILITIES[udfType].includes(capability);
12150
+ }
12098
12151
  function assertSyscallCapability(udfType, capability, operation) {
12099
- if (CAPABILITY_UDF_TYPES[capability].includes(udfType)) {
12152
+ if (hasSyscallCapability(udfType, capability)) {
12100
12153
  return;
12101
12154
  }
12102
12155
  throw new Error(`${operation} not available in ${formatUdfType(udfType)}`);
@@ -12115,6 +12168,12 @@ function formatUdfType(udfType) {
12115
12168
  }
12116
12169
 
12117
12170
  // ../core/dist/kernel/syscalls/action-syscalls.js
12171
+ var NESTED_UDF_OPERATION = {
12172
+ query: "Nested queries",
12173
+ mutation: "Nested mutations",
12174
+ action: "Nested actions"
12175
+ };
12176
+
12118
12177
  class ActionSyscalls {
12119
12178
  context;
12120
12179
  queryRuntime;
@@ -12140,7 +12199,7 @@ class ActionSyscalls {
12140
12199
  router.registerAsync(this.ops.createFunctionHandle, (args) => this.handleCreateFunctionHandle(args));
12141
12200
  }
12142
12201
  async handleActionQuery(args) {
12143
- this.requireNestedQuery();
12202
+ this.requireNestedCall("query");
12144
12203
  const target = resolveFunctionTarget(args, this.context.componentPath);
12145
12204
  const udfArguments = normalizeUdfArgsPayload(args.args);
12146
12205
  return await this.invocationManager.execute(target.udfPath, udfArguments, "query", target.componentPath);
@@ -12174,15 +12233,8 @@ class ActionSyscalls {
12174
12233
  assertSyscallCapability(this.context.udfType, "actionSearch", "Search");
12175
12234
  return this.queryRuntime.runSearchAction(args.query);
12176
12235
  }
12177
- requireNestedQuery() {
12178
- assertSyscallCapability(this.context.udfType, "nestedQuery", "Nested queries");
12179
- }
12180
12236
  requireNestedCall(type) {
12181
- if (type === "query") {
12182
- this.requireNestedQuery();
12183
- return;
12184
- }
12185
- assertSyscallCapability(this.context.udfType, type === "mutation" ? "nestedMutation" : "nestedAction", type === "mutation" ? "Nested mutations" : "Nested actions");
12237
+ assertSyscallCapability(this.context.udfType, NESTED_UDF_CAPABILITY[type], NESTED_UDF_OPERATION[type]);
12186
12238
  }
12187
12239
  }
12188
12240
 
@@ -12518,7 +12570,7 @@ class HeadroomSyscalls {
12518
12570
  router.registerAsync(this.ops.headroom, async () => this.handleHeadroom());
12519
12571
  }
12520
12572
  handleHeadroom() {
12521
- if (this.context.udfType !== "query" && this.context.udfType !== "mutation") {
12573
+ if (!hasSyscallCapability(this.context.udfType, "transactionHeadroom")) {
12522
12574
  throw new Error(`Unknown async operation: ${this.ops.headroom}`);
12523
12575
  }
12524
12576
  return this.context.getTransactionHeadroom();
@@ -12539,14 +12591,14 @@ class IdentitySyscalls {
12539
12591
  }
12540
12592
  handleGetUserIdentity() {
12541
12593
  this.context.markAuthAccessed();
12542
- const authContext2 = this.context.authContext;
12543
- if (!authContext2) {
12594
+ const authContext = this.context.authContext;
12595
+ if (!authContext) {
12544
12596
  return null;
12545
12597
  }
12546
- if (authContext2.userIdentity) {
12547
- return authContext2.userIdentity;
12598
+ if (authContext.userIdentity) {
12599
+ return authContext.userIdentity;
12548
12600
  }
12549
- const token = authContext2.token;
12601
+ const token = authContext.token;
12550
12602
  if (!token) {
12551
12603
  return null;
12552
12604
  }
@@ -12585,14 +12637,16 @@ class JsSyscallRouter {
12585
12637
 
12586
12638
  // ../core/dist/kernel/syscalls/query-syscalls.js
12587
12639
  class QuerySyscalls {
12588
- queryRuntime;
12589
12640
  nextQueryId = 1;
12590
12641
  queryResults = {};
12591
12642
  pendingQueries = {};
12643
+ context;
12644
+ queryRuntime;
12592
12645
  ops;
12593
- constructor(queryRuntime, ops = CONVEX_1_0_SYSCALL_API.query) {
12594
- this.queryRuntime = queryRuntime;
12595
- this.ops = ops;
12646
+ constructor(options) {
12647
+ this.context = options.context;
12648
+ this.queryRuntime = options.queryRuntime;
12649
+ this.ops = options.ops ?? CONVEX_1_0_SYSCALL_API.query;
12596
12650
  }
12597
12651
  register(router) {
12598
12652
  router.registerSync(this.ops.queryStream, (args) => this.handleQueryStream(args));
@@ -12601,18 +12655,21 @@ class QuerySyscalls {
12601
12655
  router.registerAsync(this.ops.queryPage, (args) => this.handleQueryPage(args));
12602
12656
  }
12603
12657
  handleQueryStream(args) {
12658
+ this.requireDatabaseRead();
12604
12659
  const { query } = args;
12605
12660
  const queryId = this.nextQueryId++;
12606
12661
  this.pendingQueries[queryId] = query;
12607
12662
  return { queryId };
12608
12663
  }
12609
12664
  handleQueryCleanup(args) {
12665
+ this.requireDatabaseRead();
12610
12666
  const queryId = args.queryId;
12611
12667
  delete this.pendingQueries[queryId];
12612
12668
  delete this.queryResults[queryId];
12613
12669
  return {};
12614
12670
  }
12615
12671
  async handleQueryStreamNext(args) {
12672
+ this.requireDatabaseRead();
12616
12673
  const queryId = args.queryId;
12617
12674
  if (this.pendingQueries[queryId]) {
12618
12675
  const query = this.pendingQueries[queryId];
@@ -12632,6 +12689,7 @@ class QuerySyscalls {
12632
12689
  return { value, done: false };
12633
12690
  }
12634
12691
  async handleQueryPage(args) {
12692
+ this.requireDatabaseRead();
12635
12693
  const { query, cursor, pageSize } = args;
12636
12694
  if (cursor === "_end_cursor") {
12637
12695
  return {
@@ -12647,6 +12705,9 @@ class QuerySyscalls {
12647
12705
  continueCursor: paginatedResult.hasMore ? paginatedResult.nextCursor : "_end_cursor"
12648
12706
  };
12649
12707
  }
12708
+ requireDatabaseRead() {
12709
+ assertSyscallCapability(this.context.udfType, "databaseRead", "Database reads");
12710
+ }
12650
12711
  }
12651
12712
 
12652
12713
  // ../core/dist/kernel/syscalls/schedule-syscalls.js
@@ -12660,15 +12721,17 @@ class ScheduleSyscalls {
12660
12721
  this.ops = options.ops ?? CONVEX_1_0_SYSCALL_API.schedule;
12661
12722
  }
12662
12723
  register(router) {
12663
- router.registerAsync(this.ops.schedule, (args) => this.handleSchedule(args, false), { argsFormat: "convex" });
12664
- router.registerAsync(this.ops.scheduleFromAction, (args) => this.handleSchedule(args, true), {
12724
+ router.registerAsync(this.ops.schedule, (args) => this.handleSchedule(args, "mutationScheduler"), {
12665
12725
  argsFormat: "convex"
12666
12726
  });
12667
- router.registerAsync(this.ops.cancelJobFromAction, (args) => this.handleCancelJob(args, true));
12668
- router.registerAsync(this.ops.cancelJob, (args) => this.handleCancelJob(args, false));
12727
+ router.registerAsync(this.ops.scheduleFromAction, (args) => this.handleSchedule(args, "actionScheduler"), {
12728
+ argsFormat: "convex"
12729
+ });
12730
+ router.registerAsync(this.ops.cancelJobFromAction, (args) => this.handleCancelJob(args, "actionScheduler"));
12731
+ router.registerAsync(this.ops.cancelJob, (args) => this.handleCancelJob(args, "mutationScheduler"));
12669
12732
  }
12670
- async handleSchedule(args, isAction) {
12671
- this.requireScheduler(isAction);
12733
+ async handleSchedule(args, capability) {
12734
+ this.requireScheduler(capability);
12672
12735
  const target = resolveFunctionTarget(args, this.context.componentPath);
12673
12736
  const { args: fnArgs, ts } = args;
12674
12737
  if (fnArgs === undefined || typeof ts !== "number") {
@@ -12677,8 +12740,8 @@ class ScheduleSyscalls {
12677
12740
  const componentPathForJob = normalizeComponentPathValue(target.componentPath ?? this.context.componentPath);
12678
12741
  return this.scheduler.schedule(target.udfPath, fnArgs, ts, componentPathForJob);
12679
12742
  }
12680
- async handleCancelJob(args, isAction) {
12681
- this.requireScheduler(isAction);
12743
+ async handleCancelJob(args, capability) {
12744
+ this.requireScheduler(capability);
12682
12745
  const { id, state } = args;
12683
12746
  if (typeof id !== "string") {
12684
12747
  throw new Error("`id` argument for `cancel_job` must be a string.");
@@ -12686,8 +12749,8 @@ class ScheduleSyscalls {
12686
12749
  await this.scheduler.cancel(id, state);
12687
12750
  return {};
12688
12751
  }
12689
- requireScheduler(isAction) {
12690
- assertSyscallCapability(this.context.udfType, isAction ? "actionScheduler" : "mutationScheduler", "Scheduler");
12752
+ requireScheduler(capability) {
12753
+ assertSyscallCapability(this.context.udfType, capability, "Scheduler");
12691
12754
  }
12692
12755
  }
12693
12756
 
@@ -12829,7 +12892,11 @@ class KernelSyscalls {
12829
12892
  context: resources.context,
12830
12893
  udfExecutor: resources.udfExecutor
12831
12894
  });
12832
- new QuerySyscalls(resources.queryRuntime, syscallApi.query).register(this.router);
12895
+ new QuerySyscalls({
12896
+ context: resources.context,
12897
+ queryRuntime: resources.queryRuntime,
12898
+ ops: syscallApi.query
12899
+ }).register(this.router);
12833
12900
  new DatabaseSyscalls({
12834
12901
  context: resources.context,
12835
12902
  docStore: resources.docStore,
@@ -13559,6 +13626,16 @@ function rangesToTables(ranges) {
13559
13626
  }
13560
13627
  return tables;
13561
13628
  }
13629
+ function cloneSetMap(source) {
13630
+ const clone = new Map;
13631
+ copySetMap(source, clone);
13632
+ return clone;
13633
+ }
13634
+ function copySetMap(source, target) {
13635
+ for (const [key, values] of source) {
13636
+ target.set(key, new Set(values));
13637
+ }
13638
+ }
13562
13639
  var TABLE_WRITE_TIMESTAMP_TTL_MS = 60 * 60 * 1000;
13563
13640
  var RECENT_WRITE_RANGE_TTL_MS = 60 * 1000;
13564
13641
  var TABLE_WRITE_TIMESTAMP_MAX_SIZE = 1e4;
@@ -13572,6 +13649,30 @@ class SubscriptionGraph {
13572
13649
  clientQueryToId = new Map;
13573
13650
  hashToTables = new Map;
13574
13651
  tableToHashes = new Map;
13652
+ apply(change) {
13653
+ const snapshot = this.snapshot();
13654
+ try {
13655
+ switch (change.type) {
13656
+ case "subscribe":
13657
+ this.setClientQueryHash(change.clientQuery, change.queryId, change.queryHash);
13658
+ this.setQueryTables(change.queryHash, change.tables);
13659
+ break;
13660
+ case "unsubscribe":
13661
+ this.removeClientQuery(change.clientQuery);
13662
+ break;
13663
+ case "unsubscribeClient":
13664
+ this.removeClient(change.clientId);
13665
+ break;
13666
+ case "renameClient":
13667
+ this.renameClient(change.oldClientId, change.newClientId);
13668
+ break;
13669
+ }
13670
+ this.assertConsistent();
13671
+ } catch (error) {
13672
+ this.restore(snapshot);
13673
+ throw error;
13674
+ }
13675
+ }
13575
13676
  getClientQueriesForHash(hash) {
13576
13677
  return this.hashToClientQueries.get(hash) ?? new Set;
13577
13678
  }
@@ -13624,6 +13725,11 @@ class SubscriptionGraph {
13624
13725
  const hash = this.clientQueryToHash.get(oldKey);
13625
13726
  if (!hash)
13626
13727
  return;
13728
+ if (oldKey === newKey) {
13729
+ this.clientQueryToId.set(oldKey, newQueryId);
13730
+ return;
13731
+ }
13732
+ this.removeClientQuery(newKey);
13627
13733
  this.clientQueryToHash.delete(oldKey);
13628
13734
  this.clientQueryToId.delete(oldKey);
13629
13735
  this.clientQueryToHash.set(newKey, hash);
@@ -13632,6 +13738,54 @@ class SubscriptionGraph {
13632
13738
  cqSet.delete(oldKey);
13633
13739
  cqSet.add(newKey);
13634
13740
  }
13741
+ assertConsistent() {
13742
+ for (const [hash, clientQueries] of this.hashToClientQueries) {
13743
+ if (clientQueries.size === 0) {
13744
+ throw new Error(`SubscriptionGraph invariant failed: empty client query set for ${hash}`);
13745
+ }
13746
+ for (const clientQuery of clientQueries) {
13747
+ if (this.clientQueryToHash.get(clientQuery) !== hash) {
13748
+ throw new Error(`SubscriptionGraph invariant failed: stale client query ${clientQuery} for ${hash}`);
13749
+ }
13750
+ if (!this.clientQueryToId.has(clientQuery)) {
13751
+ throw new Error(`SubscriptionGraph invariant failed: missing query id for ${clientQuery}`);
13752
+ }
13753
+ }
13754
+ }
13755
+ for (const [clientQuery, hash] of this.clientQueryToHash) {
13756
+ if (!this.hashToClientQueries.get(hash)?.has(clientQuery)) {
13757
+ throw new Error(`SubscriptionGraph invariant failed: missing reverse hash entry for ${clientQuery}`);
13758
+ }
13759
+ if (!this.clientQueryToId.has(clientQuery)) {
13760
+ throw new Error(`SubscriptionGraph invariant failed: missing query id for ${clientQuery}`);
13761
+ }
13762
+ }
13763
+ for (const clientQuery of this.clientQueryToId.keys()) {
13764
+ if (!this.clientQueryToHash.has(clientQuery)) {
13765
+ throw new Error(`SubscriptionGraph invariant failed: orphaned query id for ${clientQuery}`);
13766
+ }
13767
+ }
13768
+ for (const [hash, tables] of this.hashToTables) {
13769
+ if (!this.hashToClientQueries.has(hash)) {
13770
+ throw new Error(`SubscriptionGraph invariant failed: table dependencies for orphaned hash ${hash}`);
13771
+ }
13772
+ for (const table of tables) {
13773
+ if (!this.tableToHashes.get(table)?.has(hash)) {
13774
+ throw new Error(`SubscriptionGraph invariant failed: missing reverse table entry for ${hash} on ${table}`);
13775
+ }
13776
+ }
13777
+ }
13778
+ for (const [table, hashes] of this.tableToHashes) {
13779
+ if (hashes.size === 0) {
13780
+ throw new Error(`SubscriptionGraph invariant failed: empty hash set for table ${table}`);
13781
+ }
13782
+ for (const hash of hashes) {
13783
+ if (!this.hashToTables.get(hash)?.has(table)) {
13784
+ throw new Error(`SubscriptionGraph invariant failed: stale table hash ${hash} for ${table}`);
13785
+ }
13786
+ }
13787
+ }
13788
+ }
13635
13789
  setQueryTables(hash, tables) {
13636
13790
  if (!this.hashToClientQueries.has(hash))
13637
13791
  return;
@@ -13687,6 +13841,56 @@ class SubscriptionGraph {
13687
13841
  *hashes() {
13688
13842
  yield* this.hashToClientQueries.keys();
13689
13843
  }
13844
+ removeClient(clientId) {
13845
+ const prefix = `${clientId}:`;
13846
+ const keysToRemove = [];
13847
+ for (const [key] of this.clientQueryToHash) {
13848
+ if (key.startsWith(prefix)) {
13849
+ keysToRemove.push(key);
13850
+ }
13851
+ }
13852
+ for (const key of keysToRemove) {
13853
+ this.removeClientQuery(key);
13854
+ }
13855
+ }
13856
+ renameClient(oldClientId, newClientId) {
13857
+ const prefix = `${oldClientId}:`;
13858
+ const updates = [];
13859
+ for (const [key] of this.clientQueryToHash) {
13860
+ if (key.startsWith(prefix)) {
13861
+ const queryId = this.clientQueryToId.get(key);
13862
+ if (queryId !== undefined) {
13863
+ updates.push({ oldKey: key, newKey: makeClientQueryKey(newClientId, queryId), queryId });
13864
+ }
13865
+ }
13866
+ }
13867
+ for (const { oldKey, newKey, queryId } of updates) {
13868
+ this.renameClientQuery(oldKey, newKey, queryId);
13869
+ }
13870
+ }
13871
+ snapshot() {
13872
+ return {
13873
+ hashToClientQueries: cloneSetMap(this.hashToClientQueries),
13874
+ clientQueryToHash: new Map(this.clientQueryToHash),
13875
+ clientQueryToId: new Map(this.clientQueryToId),
13876
+ hashToTables: cloneSetMap(this.hashToTables),
13877
+ tableToHashes: cloneSetMap(this.tableToHashes)
13878
+ };
13879
+ }
13880
+ restore(snapshot) {
13881
+ this.hashToClientQueries.clear();
13882
+ this.clientQueryToHash.clear();
13883
+ this.clientQueryToId.clear();
13884
+ this.hashToTables.clear();
13885
+ this.tableToHashes.clear();
13886
+ copySetMap(snapshot.hashToClientQueries, this.hashToClientQueries);
13887
+ for (const [key, value] of snapshot.clientQueryToHash)
13888
+ this.clientQueryToHash.set(key, value);
13889
+ for (const [key, value] of snapshot.clientQueryToId)
13890
+ this.clientQueryToId.set(key, value);
13891
+ copySetMap(snapshot.hashToTables, this.hashToTables);
13892
+ copySetMap(snapshot.tableToHashes, this.tableToHashes);
13893
+ }
13690
13894
  }
13691
13895
 
13692
13896
  class SubscriptionManager {
@@ -13697,9 +13901,14 @@ class SubscriptionManager {
13697
13901
  subscribe(clientId, queryId, dependencies, queryHash, snapshotTimestamp) {
13698
13902
  const hash = queryHash ?? makeClientQueryKey(clientId, queryId);
13699
13903
  const clientQueryKey = makeClientQueryKey(clientId, queryId);
13700
- this.graph.setClientQueryHash(clientQueryKey, queryId, hash);
13701
13904
  const tables = rangesToTables(dependencies.ranges);
13702
- this.graph.setQueryTables(hash, tables);
13905
+ this.graph.apply({
13906
+ type: "subscribe",
13907
+ clientQuery: clientQueryKey,
13908
+ queryId,
13909
+ queryHash: hash,
13910
+ tables
13911
+ });
13703
13912
  let needsRerun = false;
13704
13913
  const now = Date.now();
13705
13914
  const preciseCheckedTables = new Set;
@@ -13742,18 +13951,10 @@ class SubscriptionManager {
13742
13951
  }
13743
13952
  unsubscribe(clientId, queryId) {
13744
13953
  const clientQueryKey = makeClientQueryKey(clientId, queryId);
13745
- this.graph.removeClientQuery(clientQueryKey);
13954
+ this.graph.apply({ type: "unsubscribe", clientQuery: clientQueryKey });
13746
13955
  }
13747
13956
  unsubscribeAll(clientId) {
13748
- const keysToRemove = [];
13749
- for (const [key] of this.graph.clientQueries()) {
13750
- if (key.startsWith(`${clientId}:`)) {
13751
- keysToRemove.push(key);
13752
- }
13753
- }
13754
- for (const key of keysToRemove) {
13755
- this.graph.removeClientQuery(key);
13756
- }
13957
+ this.graph.apply({ type: "unsubscribeClient", clientId });
13757
13958
  }
13758
13959
  findAffectedQueries(writtenRanges) {
13759
13960
  const writtenTables = rangesToTables(writtenRanges);
@@ -13864,18 +14065,7 @@ class SubscriptionManager {
13864
14065
  return queries;
13865
14066
  }
13866
14067
  updateSessionId(oldClientId, newClientId) {
13867
- const updates = [];
13868
- for (const [key] of this.graph.clientQueries()) {
13869
- if (key.startsWith(`${oldClientId}:`)) {
13870
- const queryId = this.graph.getOriginalQueryId(key);
13871
- if (queryId !== undefined) {
13872
- updates.push({ oldKey: key, newKey: makeClientQueryKey(newClientId, queryId), queryId });
13873
- }
13874
- }
13875
- }
13876
- for (const { oldKey, newKey, queryId } of updates) {
13877
- this.graph.renameClientQuery(oldKey, newKey, queryId);
13878
- }
14068
+ this.graph.apply({ type: "renameClient", oldClientId, newClientId });
13879
14069
  }
13880
14070
  getStats() {
13881
14071
  const clients = new Set;
@@ -13890,7 +14080,9 @@ class SubscriptionManager {
13890
14080
  totalTrackedWriteTimestamps: this.tableWriteTimestamps.size
13891
14081
  };
13892
14082
  }
13893
- assertConsistency() {}
14083
+ assertConsistency() {
14084
+ this.graph.assertConsistent();
14085
+ }
13894
14086
  forceCleanupTableWriteTimestamps() {
13895
14087
  const sizeBefore = this.tableWriteTimestamps.size;
13896
14088
  this.lastCleanupTime = 0;
@@ -14340,13 +14532,13 @@ var udfMathRandom2 = () => {
14340
14532
  const udfRuntime = UDF_ASYNC_CONTEXT.getStore();
14341
14533
  return (udfRuntime?.mathRandom ?? OG_MATH_RANDOM)();
14342
14534
  };
14343
- var udfSetInterval = (callback, delay) => {
14535
+ var udfSetInterval = (callback, delay, ...args) => {
14344
14536
  const udfRuntime = UDF_ASYNC_CONTEXT.getStore();
14345
- return (udfRuntime?.setInterval ?? OG_SET_INTERVAL)(callback, delay ?? 0);
14537
+ return (udfRuntime?.setInterval ?? OG_SET_INTERVAL)(callback, delay ?? 0, ...args);
14346
14538
  };
14347
- var udfSetTimeout = (callback, delay) => {
14539
+ var udfSetTimeout = (callback, delay, ...args) => {
14348
14540
  const udfRuntime = UDF_ASYNC_CONTEXT.getStore();
14349
- return (udfRuntime?.setTimeout ?? OG_SET_TIMEOUT)(callback, delay ?? 0);
14541
+ return (udfRuntime?.setTimeout ?? OG_SET_TIMEOUT)(callback, delay ?? 0, ...args);
14350
14542
  };
14351
14543
  var udfCryptoRandomUUID2 = () => {
14352
14544
  const udfRuntime = UDF_ASYNC_CONTEXT.getStore();
@@ -14420,15 +14612,19 @@ function resolveSeed(kind, requestId, tnow) {
14420
14612
  fallbackSeedCounter += 1;
14421
14613
  return `udf:${kind}:${tnow}:${fallbackSeedCounter}:${OG_CRYPTO_RANDOM_UUID()}`;
14422
14614
  }
14615
+ function isKernelAuthContext(auth) {
14616
+ return !!auth && typeof auth === "object" && "tokenType" in auth && (auth.tokenType === "Admin" || auth.tokenType === "System" || auth.tokenType === "User" || auth.tokenType === "None");
14617
+ }
14423
14618
  function resolveEffectiveKernelAuth(auth) {
14424
14619
  const ambientIdentity = getAuthContext();
14425
- if (auth && typeof auth === "object" && "tokenType" in auth) {
14620
+ if (isKernelAuthContext(auth)) {
14426
14621
  return {
14427
14622
  ...auth,
14428
14623
  userIdentity: auth.userIdentity ?? ambientIdentity
14429
14624
  };
14430
14625
  }
14431
- return ambientIdentity ?? auth;
14626
+ const userIdentity = ambientIdentity ?? auth;
14627
+ return userIdentity ? { tokenType: "User", userIdentity } : undefined;
14432
14628
  }
14433
14629
  function resolveExecutionIdGenerator(deterministicSeed, explicitIdGenerator) {
14434
14630
  if (explicitIdGenerator) {
@@ -14437,20 +14633,12 @@ function resolveExecutionIdGenerator(deterministicSeed, explicitIdGenerator) {
14437
14633
  return idGeneratorContext.getStore() ?? (deterministicSeed ? createDeterministicIdGenerator(deterministicSeed) : undefined);
14438
14634
  }
14439
14635
  function createExecutionKernel(options) {
14440
- const capabilities = {};
14441
- if (options.storage) {
14442
- capabilities.blobs = { store: options.storage, consistency: "eventual" };
14443
- }
14444
- if (options.searchstore) {
14445
- capabilities.search = options.searchstore;
14446
- }
14447
- if (options.vecstore) {
14448
- capabilities.vector = options.vecstore;
14449
- }
14450
14636
  const convex = buildKernel({
14451
14637
  services: {
14452
14638
  docstore: options.docstore,
14453
- capabilities,
14639
+ ...options.storage ? { blobstore: options.storage } : {},
14640
+ ...options.searchstore ? { searchstore: options.searchstore } : {},
14641
+ ...options.vecstore ? { vecstore: options.vecstore } : {},
14454
14642
  udfExecutor: options.udfExecutor
14455
14643
  },
14456
14644
  authContext: resolveEffectiveKernelAuth(options.auth),
@@ -14721,6 +14909,82 @@ async function runUdfHttpAction(docstore, fn, auth, storage2, searchstore2, vecs
14721
14909
 
14722
14910
  // ../core/dist/udf/executor/inline.js
14723
14911
  init_module_loader();
14912
+
14913
+ // ../core/dist/udf/function-resolution.js
14914
+ function normalizeUdfFunctionTarget(input, options = {}) {
14915
+ const policy = options.policy ?? {};
14916
+ if (input.startsWith("function://")) {
14917
+ if (policy.allowFunctionHandle === false) {
14918
+ throw new Error(`Invalid UDF path: ${input}`);
14919
+ }
14920
+ const remainder = input.slice("function://".length);
14921
+ const separatorIndex = remainder.indexOf(";");
14922
+ if (separatorIndex === -1) {
14923
+ throw new Error(`Invalid function handle: ${input}`);
14924
+ }
14925
+ const componentPath = normalizeComponentPath2(remainder.slice(0, separatorIndex));
14926
+ const udfPath = remainder.slice(separatorIndex + 1);
14927
+ const target = normalizePlainUdfPath(udfPath, {
14928
+ componentPath: componentPath ?? options.componentPath,
14929
+ policy
14930
+ });
14931
+ return {
14932
+ ...target,
14933
+ componentPath: componentPath ?? target.componentPath,
14934
+ isFunctionHandle: true
14935
+ };
14936
+ }
14937
+ return normalizePlainUdfPath(input, options);
14938
+ }
14939
+ function classifyUdfFunction(fn) {
14940
+ if (fn === null || typeof fn !== "object" && typeof fn !== "function") {
14941
+ return null;
14942
+ }
14943
+ const types = [];
14944
+ if (fn.isQuery)
14945
+ types.push("query");
14946
+ if (fn.isMutation)
14947
+ types.push("mutation");
14948
+ if (fn.isAction)
14949
+ types.push("action");
14950
+ return types.length === 1 ? types[0] : null;
14951
+ }
14952
+ function normalizePlainUdfPath(input, options = {}) {
14953
+ const policy = options.policy ?? {};
14954
+ let path = input;
14955
+ if (policy.allowSlashPath && !path.includes(":") && path.includes("/")) {
14956
+ const lastSlash = path.lastIndexOf("/");
14957
+ path = path.substring(0, lastSlash) + ":" + path.substring(lastSlash + 1);
14958
+ }
14959
+ const parts = path.split(":");
14960
+ if (parts.length === 2 && parts[0].length > 0 && parts[1].length > 0) {
14961
+ return {
14962
+ path,
14963
+ modulePath: parts[0],
14964
+ exportName: parts[1],
14965
+ componentPath: normalizeComponentPath2(options.componentPath),
14966
+ isFunctionHandle: false
14967
+ };
14968
+ }
14969
+ if (parts.length === 1 && policy.allowDefaultExport && parts[0].length > 0) {
14970
+ return {
14971
+ path: `${parts[0]}:default`,
14972
+ modulePath: parts[0],
14973
+ exportName: "default",
14974
+ componentPath: normalizeComponentPath2(options.componentPath),
14975
+ isFunctionHandle: false
14976
+ };
14977
+ }
14978
+ throw new Error(`Invalid UDF path: ${input}`);
14979
+ }
14980
+ function normalizeComponentPath2(componentPath) {
14981
+ if (!componentPath) {
14982
+ return;
14983
+ }
14984
+ return componentPath.length > 0 ? componentPath : undefined;
14985
+ }
14986
+
14987
+ // ../core/dist/udf/executor/inline.js
14724
14988
  init_validator2();
14725
14989
 
14726
14990
  // ../core/dist/errors/index.js
@@ -14890,22 +15154,8 @@ class InlineUdfExecutor {
14890
15154
  this.bootstrapState = options.bootstrapState ?? new InlineExecutorBootstrapState;
14891
15155
  }
14892
15156
  withAmbientAuth(auth, fn) {
14893
- let authContext2;
14894
- let userIdentity;
14895
- if (auth && typeof auth === "object" && "tokenType" in auth) {
14896
- authContext2 = auth;
14897
- userIdentity = authContext2.tokenType === "User" && !authContext2.userIdentity && authContext2.token ? identityFromTrustedToken(authContext2.token) : authContext2.userIdentity;
14898
- if (userIdentity && authContext2.tokenType === "User") {
14899
- authContext2 = {
14900
- ...authContext2,
14901
- userIdentity
14902
- };
14903
- }
14904
- } else {
14905
- userIdentity = auth;
14906
- }
14907
- const principal2 = authContext2 ? legacyAuthContextToPrincipal(authContext2) : userIdentity ? legacyAuthContextToPrincipal({ tokenType: "User", userIdentity }) : legacyAuthContextToPrincipal({ tokenType: "None" });
14908
- return runWithAuth(userIdentity, fn, principal2);
15157
+ const executionAuth = resolveExecutionAuth(auth);
15158
+ return runWithAuth(executionAuth.userIdentity, fn, executionAuth.authContext);
14909
15159
  }
14910
15160
  get docstore() {
14911
15161
  return this.services.docstore;
@@ -14921,27 +15171,32 @@ class InlineUdfExecutor {
14921
15171
  }
14922
15172
  async execute(functionPath, args, udfType, auth, componentPath, requestId, snapshotTimestamp) {
14923
15173
  const bootstrapTiming = await this.ensureBootstrapped();
14924
- const [moduleName, functionName2] = this.parseUdfPath(functionPath);
14925
- const finalRequestId = requestId ?? this.requestIdFactory(udfType, functionPath);
14926
- const isSystemFunction = moduleName === "_system" || functionPath.startsWith("_system:");
15174
+ const target = normalizeUdfFunctionTarget(functionPath, {
15175
+ componentPath,
15176
+ policy: { allowFunctionHandle: true }
15177
+ });
15178
+ const { modulePath: moduleName, exportName: functionName2 } = target;
15179
+ const finalRequestId = requestId ?? this.requestIdFactory(udfType, target.path);
15180
+ const executionAuth = resolveExecutionAuth(auth);
15181
+ const isSystemFunction = moduleName === "_system" || target.path.startsWith("_system:");
14927
15182
  const startTime = performance.now();
14928
15183
  const invokeUdf = async () => {
14929
- const module = await withTraceSpan("udf.load_module", "runtime", () => this.loadModule(moduleName, componentPath), { moduleName, componentPath: componentPath ?? "" });
15184
+ const module = await withTraceSpan("udf.load_module", "runtime", () => this.loadModule(moduleName, target.componentPath), { moduleName, componentPath: target.componentPath ?? "" });
14930
15185
  const fn = module?.[functionName2];
14931
- this.assertFunctionExport(functionName2, moduleName, fn, udfType, auth);
14932
- await withTraceSpan("udf.validate_args", "runtime", () => this.validateArgs(fn, args, componentPath), {
15186
+ const resolvedType = this.assertFunctionExport(functionName2, moduleName, fn, udfType, executionAuth.executorAuth);
15187
+ await withTraceSpan("udf.validate_args", "runtime", () => this.validateArgs(fn, args, target.componentPath), {
14933
15188
  moduleName,
14934
15189
  functionName: functionName2,
14935
- componentPath: componentPath ?? ""
15190
+ componentPath: target.componentPath ?? ""
14936
15191
  });
14937
15192
  const argsString = JSON.stringify(convexToJson([args]));
14938
- if (fn.isQuery) {
15193
+ if (resolvedType === "query") {
14939
15194
  return withTraceSpan("udf.invoke_query", "runtime", async () => JSON.parse(await fn.invokeQuery(argsString)), { moduleName, functionName: functionName2 });
14940
15195
  }
14941
- if (fn.isMutation) {
15196
+ if (resolvedType === "mutation") {
14942
15197
  return withTraceSpan("udf.invoke_mutation", "runtime", async () => JSON.parse(await fn.invokeMutation(argsString)), { moduleName, functionName: functionName2 });
14943
15198
  }
14944
- if (fn.isAction) {
15199
+ if (resolvedType === "action") {
14945
15200
  return withTraceSpan("udf.invoke_action", "runtime", async () => JSON.parse(await fn.invokeAction(finalRequestId, argsString)), { moduleName, functionName: functionName2 });
14946
15201
  }
14947
15202
  throw new Error(`Function "${functionName2}" has no valid type`);
@@ -14951,15 +15206,15 @@ class InlineUdfExecutor {
14951
15206
  type: udfType,
14952
15207
  docstore: this.docstore,
14953
15208
  fn: invokeUdf,
14954
- auth,
15209
+ auth: executionAuth.executorAuth,
14955
15210
  storage: this.blobstore,
14956
15211
  searchstore: this.searchstore,
14957
15212
  vecstore: this.vecstore,
14958
15213
  requestId: finalRequestId,
14959
15214
  udfExecutor: this,
14960
- componentPath,
15215
+ componentPath: target.componentPath,
14961
15216
  snapshotOverride: udfType === "query" ? snapshotTimestamp : undefined,
14962
- functionPath,
15217
+ functionPath: target.path,
14963
15218
  tableRegistry: this.tableRegistry
14964
15219
  });
14965
15220
  };
@@ -14970,7 +15225,7 @@ class InlineUdfExecutor {
14970
15225
  const duration = performance.now() - startTime;
14971
15226
  const logEntry = {
14972
15227
  timestamp: Date.now(),
14973
- functionName: functionPath,
15228
+ functionName: target.path,
14974
15229
  functionType: udfType,
14975
15230
  status: "success",
14976
15231
  duration: Math.round(duration * 100) / 100,
@@ -15029,6 +15284,7 @@ class InlineUdfExecutor {
15029
15284
  }
15030
15285
  const runHttpUdf = () => resolvedRoute.handler.invokeHttpAction(request);
15031
15286
  const finalRequestId = requestId ?? this.requestIdFactory("http", `${request.method}:${url.pathname}`);
15287
+ const executionAuth = resolveExecutionAuth(auth);
15032
15288
  const functionPath = `${request.method} ${url.pathname}`;
15033
15289
  const startTime = performance.now();
15034
15290
  const recordHttpExecution = (status, extra) => {
@@ -15058,9 +15314,9 @@ class InlineUdfExecutor {
15058
15314
  try {
15059
15315
  const response = await this.withAmbientAuth(auth, async () => {
15060
15316
  if (!this.moduleRegistry) {
15061
- return runUdfHttpAction(this.docstore, runHttpUdf, auth, this.blobstore, this.searchstore, this.vecstore, finalRequestId, this, resolvedRoute.componentPath);
15317
+ return runUdfHttpAction(this.docstore, runHttpUdf, executionAuth.executorAuth, this.blobstore, this.searchstore, this.vecstore, finalRequestId, this, resolvedRoute.componentPath);
15062
15318
  }
15063
- return withModuleRegistry(this.moduleRegistry, () => runUdfHttpAction(this.docstore, runHttpUdf, auth, this.blobstore, this.searchstore, this.vecstore, finalRequestId, this, resolvedRoute.componentPath));
15319
+ return withModuleRegistry(this.moduleRegistry, () => runUdfHttpAction(this.docstore, runHttpUdf, executionAuth.executorAuth, this.blobstore, this.searchstore, this.vecstore, finalRequestId, this, resolvedRoute.componentPath));
15064
15320
  });
15065
15321
  recordHttpExecution("success", { statusCode: response.status });
15066
15322
  return response;
@@ -15154,23 +15410,21 @@ class InlineUdfExecutor {
15154
15410
  }
15155
15411
  }
15156
15412
  parseUdfPath(functionPath) {
15157
- const parts = functionPath.split(":");
15158
- if (parts.length !== 2) {
15159
- throw new Error(`Invalid UDF path: ${functionPath}`);
15160
- }
15161
- return [parts[0], parts[1]];
15413
+ const target = normalizeUdfFunctionTarget(functionPath);
15414
+ return [target.modulePath, target.exportName];
15162
15415
  }
15163
15416
  assertFunctionExport(functionName2, moduleName, fn, udfType, auth) {
15164
15417
  if (typeof fn !== "function") {
15165
15418
  throw new Error(`Function "${functionName2}" not found in module "${moduleName}"`);
15166
15419
  }
15167
- if (udfType === "query" && !fn.isQuery) {
15420
+ const actualType = classifyUdfFunction(fn);
15421
+ if (udfType === "query" && actualType !== "query") {
15168
15422
  throw new Error(`Function "${functionName2}" is not a query`);
15169
15423
  }
15170
- if (udfType === "mutation" && !fn.isMutation) {
15424
+ if (udfType === "mutation" && actualType !== "mutation") {
15171
15425
  throw new Error(`Function "${functionName2}" is not a mutation`);
15172
15426
  }
15173
- if (udfType === "action" && !fn.isAction) {
15427
+ if (udfType === "action" && actualType !== "action") {
15174
15428
  throw new Error(`Function "${functionName2}" is not an action`);
15175
15429
  }
15176
15430
  if (fn.isInternal) {
@@ -15181,6 +15435,7 @@ class InlineUdfExecutor {
15181
15435
  throw new InternalFunctionAccessError(functionPath);
15182
15436
  }
15183
15437
  }
15438
+ return udfType;
15184
15439
  }
15185
15440
  async validateArgs(fn, args, componentPath) {
15186
15441
  const callContext2 = getCallContext();
@@ -15340,7 +15595,7 @@ init_analysis();
15340
15595
  init_module_loader();
15341
15596
  // ../core/dist/udf/execution-adapter.js
15342
15597
  init_auth_context();
15343
- init_jwt();
15598
+ init_execution_auth();
15344
15599
  // ../core/dist/http/api-router.js
15345
15600
  init_auth();
15346
15601
  init_auth_resolver();
@@ -15777,7 +16032,7 @@ class ScheduledFunctionExecutor {
15777
16032
  return [];
15778
16033
  }
15779
16034
  const tables = new Set;
15780
- for await (const entry of this.docstore.load_documents({
16035
+ for await (const entry of this.docstore.loadDocuments({
15781
16036
  min_timestamp_inclusive: sinceExclusive + 1n,
15782
16037
  max_timestamp_exclusive: maxTimestamp + 1n
15783
16038
  }, Order.Asc)) {
@@ -16455,10 +16710,10 @@ class BaseSqliteDocStore {
16455
16710
  }
16456
16711
  }
16457
16712
  }
16458
- async index_scan_rows(indexId, tableId, readTimestamp, interval, order, limit) {
16713
+ async indexScanRows(indexId, tableId, readTimestamp, interval, order, limit) {
16459
16714
  return this.scanIndexRows(indexId, tableId, readTimestamp, interval, order, limit);
16460
16715
  }
16461
- async index_scan_rows_after_key(indexId, tableId, readTimestamp, interval, order, resumeAfterKey, limit) {
16716
+ async indexScanRowsAfterKey(indexId, tableId, readTimestamp, interval, order, resumeAfterKey, limit) {
16462
16717
  return this.scanIndexRows(indexId, tableId, readTimestamp, interval, order, limit, resumeAfterKey);
16463
16718
  }
16464
16719
  async scanIndexRows(indexId, tableId, readTimestamp, interval, order, limit, resumeAfterKey) {
@@ -16560,13 +16815,13 @@ class BaseSqliteDocStore {
16560
16815
  }
16561
16816
  return results;
16562
16817
  }
16563
- async* index_scan(indexId, tabletId, readTimestamp, interval, order, limit) {
16564
- const rows = await this.index_scan_rows(indexId, tabletId, readTimestamp, interval, order, limit);
16818
+ async* indexScan(indexId, tabletId, readTimestamp, interval, order, limit) {
16819
+ const rows = await this.indexScanRows(indexId, tabletId, readTimestamp, interval, order, limit);
16565
16820
  for (const row of rows) {
16566
16821
  yield row;
16567
16822
  }
16568
16823
  }
16569
- async* load_documents(range, order) {
16824
+ async* loadDocuments(range, order) {
16570
16825
  const orderClause = order === Order.Asc ? "ASC" : "DESC";
16571
16826
  const query = `
16572
16827
  SELECT id, ts, table_id, json_value, deleted, prev_ts
@@ -16604,7 +16859,7 @@ class BaseSqliteDocStore {
16604
16859
  const rows = await stmt.all(key, JSON.stringify(value));
16605
16860
  return rows.length > 0;
16606
16861
  }
16607
- async previous_revisions(queries) {
16862
+ async previousRevisions(queries) {
16608
16863
  const results = new Map;
16609
16864
  const stmt = this.getPreparedStatement(`
16610
16865
  SELECT ts, json_value, deleted, prev_ts
@@ -16629,7 +16884,7 @@ class BaseSqliteDocStore {
16629
16884
  }
16630
16885
  return results;
16631
16886
  }
16632
- async previous_revisions_of_documents(queries) {
16887
+ async previousRevisionsOfDocuments(queries) {
16633
16888
  const results = new Map;
16634
16889
  const stmt = this.getPreparedStatement(`
16635
16890
  SELECT ts, json_value, deleted, prev_ts
@@ -16686,7 +16941,7 @@ class BaseSqliteDocStore {
16686
16941
  prev_ts: row.prev_ts != null ? BigInt(row.prev_ts) : null
16687
16942
  };
16688
16943
  }
16689
- async get_many(ids, readTimestamp) {
16944
+ async getMany(ids, readTimestamp) {
16690
16945
  const results = new Map;
16691
16946
  if (ids.length === 0) {
16692
16947
  return results;