@superblocksteam/library 2.0.42-next.43 → 2.0.42-next.45

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.
@@ -0,0 +1,4 @@
1
+ import { root_store_default } from "./root-store-DHEbJGYN.js";
2
+ import "./utils-CCBWAYIM.js";
3
+
4
+ export { root_store_default as default };
@@ -1,6 +1,6 @@
1
1
  import { getTracer } from "./utils-CCBWAYIM.js";
2
2
  import { NotificationPosition, SbEntityType, TriggerStepType, isValidStepDef } from "@superblocksteam/library-shared/types";
3
- import _, { get, isEmpty, isNumber, isObject, isString, isUndefined, pick, set, throttle, toNumber, toString } from "lodash";
3
+ import _, { cloneDeep, get, isEmpty, isNumber, isObject, isString, isUndefined, pick, set, throttle, toNumber, toString } from "lodash";
4
4
  import * as React$1 from "react";
5
5
  import React, { Suspense } from "react";
6
6
  import styled from "styled-components";
@@ -993,7 +993,7 @@ var registry_default = EventRegistry;
993
993
 
994
994
  //#endregion
995
995
  //#region src/lib/triggers/run-event-handlers.ts
996
- const getRootStore = () => import("./root-store-DbFURfA3.js").then((module) => module.default);
996
+ const getRootStore = () => import("./root-store-B9bo79E9.js").then((module) => module.default);
997
997
  const runEventHandlers = async ({ flow, name, scopeId, additionalContext }) => {
998
998
  const context$1 = {
999
999
  scopeId,
@@ -3257,6 +3257,149 @@ function sendNotification({ message, description, duration, key = getKey("succes
3257
3257
  });
3258
3258
  }
3259
3259
 
3260
+ //#endregion
3261
+ //#region src/lib/internal-details/lib/evaluator/file-utils.ts
3262
+ var FileManagerClass = class FileManagerClass {
3263
+ static instance;
3264
+ storage = {};
3265
+ constructor() {}
3266
+ static getInstance() {
3267
+ if (!FileManagerClass.instance) FileManagerClass.instance = new FileManagerClass();
3268
+ return FileManagerClass.instance;
3269
+ }
3270
+ store(componentName, file) {
3271
+ const fileId = getFileUploadId(file);
3272
+ if (!this.storage[componentName]) this.storage[componentName] = {};
3273
+ this.storage[componentName][fileId] = file;
3274
+ }
3275
+ get(componentName, fileId) {
3276
+ return this.storage[componentName]?.[fileId];
3277
+ }
3278
+ remove(componentName, file) {
3279
+ const fileId = getFileUploadId(file);
3280
+ if (this.storage[componentName]) delete this.storage[componentName][fileId];
3281
+ }
3282
+ clearComponent(componentName) {
3283
+ delete this.storage[componentName];
3284
+ }
3285
+ clear() {
3286
+ this.storage = {};
3287
+ }
3288
+ };
3289
+ const FileManager = FileManagerClass.getInstance();
3290
+ function getFileUploadId(file) {
3291
+ const name = file.name.replace(/[^a-zA-Z0-9.-]/g, "_");
3292
+ const size = file.size;
3293
+ const lastModified = file.lastModified;
3294
+ return `${name}-${size}-${lastModified}`;
3295
+ }
3296
+ /**
3297
+ * Check if the given object is a light readable file.
3298
+ * Meaning it has a $superblocksId property.
3299
+ *
3300
+ * Compare to `isReadableFile` which checks if the object is a full superblocks readable file object.
3301
+ */
3302
+ const isLightReadableFile = (f) => {
3303
+ if (!f || typeof f !== "object" || Array.isArray(f)) return false;
3304
+ if (Object.entries(f).length === 0) return false;
3305
+ return "$superblocksId" in f;
3306
+ };
3307
+ function getFilePaths(root, path = []) {
3308
+ const paths = [];
3309
+ if (!root || !(typeof root === "object")) return paths;
3310
+ if (Array.isArray(root) || isObservableArray(root)) {
3311
+ root.forEach((v, i) => {
3312
+ paths.push(...getFilePaths(v, [...path, i.toString()]));
3313
+ });
3314
+ return paths;
3315
+ }
3316
+ if (isLightReadableFile(root)) return [path];
3317
+ Object.entries(root).forEach(([key, value]) => {
3318
+ if (isLightReadableFile(value)) paths.push([...path, key]);
3319
+ else if (value && (Array.isArray(value) || isObservableArray(value))) value.forEach((v, i) => {
3320
+ paths.push(...getFilePaths(v, [
3321
+ ...path,
3322
+ key,
3323
+ i.toString()
3324
+ ]));
3325
+ });
3326
+ else if (value && typeof value === "object") paths.push(...getFilePaths(value, [...path, key]));
3327
+ });
3328
+ return paths;
3329
+ }
3330
+ /**
3331
+ * Extract Files and path to files from entities.
3332
+ * Used to retrieve files that are in an entity's state which is bound in a Backend API.
3333
+ * @param entities - The entities to extract files from
3334
+ * @returns
3335
+ */
3336
+ function extractFilesFromEntities(entities) {
3337
+ const files = {};
3338
+ const pathToFiles = [];
3339
+ Object.entries(entities).forEach(([entityName, entityValue]) => {
3340
+ getFilePaths(entityValue).forEach((path) => {
3341
+ const fileObj = get(entityValue, path);
3342
+ if (isLightReadableFile(fileObj)) {
3343
+ const fileId = fileObj.$superblocksId;
3344
+ const file = FileManager.get(entityName, fileId);
3345
+ if (file) {
3346
+ files[fileId] = file;
3347
+ pathToFiles.push([entityName, ...path]);
3348
+ }
3349
+ }
3350
+ });
3351
+ });
3352
+ return {
3353
+ files,
3354
+ paths: pathToFiles
3355
+ };
3356
+ }
3357
+ async function formatFilesForRequest(files) {
3358
+ const entries$1 = Object.entries(files);
3359
+ return await Promise.all(entries$1.map(async ([fileId, file]) => {
3360
+ try {
3361
+ const base64 = await new Promise((resolve, reject) => {
3362
+ const reader = new FileReader();
3363
+ reader.onload = () => resolve(reader.result.split(",")[1]);
3364
+ reader.onerror = () => reject(new Error(reader.error?.message || "Unknown error reading file"));
3365
+ reader.readAsDataURL(file);
3366
+ });
3367
+ return {
3368
+ originalName: fileId,
3369
+ buffer: base64,
3370
+ encoding: "base64",
3371
+ mimetype: "text/plain"
3372
+ };
3373
+ } catch (error) {
3374
+ console.warn(`Failed to encode file ${file.name} (ID: ${fileId}):`, error);
3375
+ throw error;
3376
+ }
3377
+ }));
3378
+ }
3379
+ function getFileWithUploadId(f) {
3380
+ const uploadId = getFileUploadId(f);
3381
+ Object.defineProperty(f, "$superblocksId", {
3382
+ value: uploadId,
3383
+ writable: false,
3384
+ enumerable: true,
3385
+ configurable: false
3386
+ });
3387
+ return f;
3388
+ }
3389
+ function getFileMetadata(f) {
3390
+ const superblocksId = getFileUploadId(f);
3391
+ const nameParts = f.name.split(".");
3392
+ const extension = nameParts.length > 1 ? nameParts.pop() || "" : "";
3393
+ return {
3394
+ $superblocksId: superblocksId,
3395
+ name: f.name,
3396
+ extension,
3397
+ type: f.type,
3398
+ size: f.size,
3399
+ encoding: "text"
3400
+ };
3401
+ }
3402
+
3260
3403
  //#endregion
3261
3404
  //#region src/lib/internal-details/lib/evaluator/binding-extraction.ts
3262
3405
  function getApiDeps(entitiesState, scopeId, apiDepCandidates) {
@@ -3274,7 +3417,32 @@ function getApiDeps(entitiesState, scopeId, apiDepCandidates) {
3274
3417
  candidates[name] = stringifySplitPaths(parts.slice(0, i - 1));
3275
3418
  } else candidates[name] = rest;
3276
3419
  });
3277
- return Object.fromEntries(Object.entries(candidates).map(([candidateName, path]) => [candidateName, buildEntityByPath(path, entitiesState.getEntity(scopeId, getName(candidateName), { includeParentScopes: true }))]).filter(([_$1, entity]) => !!entity));
3420
+ const entities = Object.fromEntries(Object.entries(candidates).map(([candidateName, path]) => [candidateName, buildEntityByPath(path, entitiesState.getEntity(scopeId, getName(candidateName), { includeParentScopes: true }))]).filter(([_$1, entity]) => !!entity));
3421
+ const { files, paths } = extractFilesFromEntities(entities);
3422
+ /**
3423
+ * Update entities data payload that rely on files,
3424
+ * to honor the FilePrivateMetadata type
3425
+ * which is checked on runtime in the backend.
3426
+ */
3427
+ const clonedEntities = /* @__PURE__ */ new Set();
3428
+ paths.forEach((path) => {
3429
+ const fileProps = get(entities, path);
3430
+ if (isLightReadableFile(fileProps)) {
3431
+ const file = FileManager.get(path[0], fileProps.$superblocksId);
3432
+ if (file) {
3433
+ const entityName = path[0];
3434
+ if (!clonedEntities.has(entityName)) {
3435
+ entities[entityName] = cloneDeep(entities[entityName]);
3436
+ clonedEntities.add(entityName);
3437
+ }
3438
+ set(entities, path, getFileMetadata(file));
3439
+ }
3440
+ }
3441
+ });
3442
+ return {
3443
+ entities,
3444
+ files
3445
+ };
3278
3446
  }
3279
3447
  function buildEntityByPath(path, entity) {
3280
3448
  if (!isObject(entity) || path === "") return entity;
@@ -3359,9 +3527,8 @@ const generateId = () => {
3359
3527
 
3360
3528
  //#endregion
3361
3529
  //#region src/lib/internal-details/lib/features/api-utils.ts
3362
- const SUPERBLOCKS_UI_EXECUTE_API_TIMEOUT_MS = 1e3 * 60 * 10;
3363
3530
  async function executeV2Api(params) {
3364
- const { body, api, notifyOnSystemError, eventType, onMessage, processStreamEvents, responseType, abortController, baseUrl, agents, viewMode, accessToken, token, traceHeaders } = params;
3531
+ const { body, controlFlowOnlyFiles, api, notifyOnSystemError, eventType, onMessage, processStreamEvents, responseType, abortController, baseUrl, viewMode, accessToken, token, traceHeaders } = params;
3365
3532
  let parentContext = context.active();
3366
3533
  if (traceHeaders) parentContext = getContextFromTraceHeaders(traceHeaders);
3367
3534
  let applicationId = "unknown";
@@ -3380,15 +3547,14 @@ async function executeV2Api(params) {
3380
3547
  } catch {
3381
3548
  cleanedBody = structuredClone(body);
3382
3549
  }
3550
+ if (controlFlowOnlyFiles && controlFlowOnlyFiles.length > 0) cleanedBody = {
3551
+ ...cleanedBody,
3552
+ files: controlFlowOnlyFiles
3553
+ };
3383
3554
  const traceContextHeaders = getTraceContextHeadersFromSpan(span);
3384
3555
  const init = {
3385
3556
  method: HttpMethod.Post,
3386
3557
  body: JSON.stringify(cleanedBody),
3387
- timeout: Number(SUPERBLOCKS_UI_EXECUTE_API_TIMEOUT_MS),
3388
- baseUrl,
3389
- responseType,
3390
- query: { eventType },
3391
- agents,
3392
3558
  signal: abortController?.signal,
3393
3559
  headers: {
3394
3560
  [SUPERBLOCKS_AUTHORIZATION_HEADER]: `Bearer ${accessToken}`,
@@ -3739,7 +3905,9 @@ var ApiManager = class {
3739
3905
  error: "No application ID was found"
3740
3906
  };
3741
3907
  }
3742
- const inputs = getApiDeps(this.rootStore.entityManager, scopeId, this.apiNameToDepCandidates[scopeId]?.[apiName] ?? []);
3908
+ const apiDepCandidates = this.apiNameToDepCandidates[scopeId]?.[apiName] ?? [];
3909
+ const { entities: inputs, files } = getApiDeps(this.rootStore.entityManager, scopeId, apiDepCandidates);
3910
+ const controlFlowOnlyFiles = await formatFilesForRequest(files);
3743
3911
  if (!this.agentUrls.length) {
3744
3912
  editorBridge.setApiResponse(apiName, {
3745
3913
  status: "STATUS_COMPLETED",
@@ -3795,6 +3963,7 @@ var ApiManager = class {
3795
3963
  includeResolved: editMode$1
3796
3964
  }
3797
3965
  },
3966
+ controlFlowOnlyFiles,
3798
3967
  api,
3799
3968
  environment: profileKey,
3800
3969
  eventType: "api",
@@ -4559,5 +4728,5 @@ var RootStore = class {
4559
4728
  var root_store_default = new RootStore();
4560
4729
 
4561
4730
  //#endregion
4562
- export { CLASS_NAMES, DEFAULT_ANONYMOUS_SOURCE_ID, DevTools, EventFlow, GLOBAL_SCOPE_ID, LazyFunction, NavigationEvent, Prop, PropsPanelCategory, RecordProp, Section, VALIDATORS, addNewPromise, colors, createInternalPropsList, createManagedPropsList, createPropertiesPanelDefinition, editorBridge, generateId, getEditStore, getName, iframeMessageHandler, isEditMode, isEmbeddedBySuperblocksFirstParty, isLocalLink, isName, isNameEqual, navigation, rejectById, resolveById, root_store_default, run_event_handlers_default, sendNotification, startEditorSync, system_error_default };
4563
- //# sourceMappingURL=root-store-mvrXQD3h.js.map
4731
+ export { CLASS_NAMES, DEFAULT_ANONYMOUS_SOURCE_ID, DevTools, EventFlow, FileManager, GLOBAL_SCOPE_ID, LazyFunction, NavigationEvent, Prop, PropsPanelCategory, RecordProp, Section, VALIDATORS, addNewPromise, colors, createInternalPropsList, createManagedPropsList, createPropertiesPanelDefinition, editorBridge, generateId, getEditStore, getFileWithUploadId, getName, iframeMessageHandler, isEditMode, isEmbeddedBySuperblocksFirstParty, isLocalLink, isName, isNameEqual, navigation, rejectById, resolveById, root_store_default, run_event_handlers_default, sendNotification, startEditorSync, system_error_default };
4732
+ //# sourceMappingURL=root-store-DHEbJGYN.js.map