@superblocksteam/library 2.0.165-next.0 → 2.0.166-next.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/jsx-dev-runtime/index.js +2 -2
- package/dist/{jsx-wrapper-BGGZod5X.js → jsx-wrapper-1kyr6-x3.js} +5 -4
- package/dist/{jsx-wrapper-BGGZod5X.js.map → jsx-wrapper-1kyr6-x3.js.map} +1 -1
- package/dist/lib/index.d.ts +5 -65
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/index.js +408 -178
- package/dist/lib/index.js.map +1 -1
- package/dist/{root-store-CtsStoaR.js → root-store-BYYXPQRA.js} +3 -402
- package/dist/root-store-BYYXPQRA.js.map +1 -0
- package/dist/{sdk-api-discovery-DdbqEI70.js → sdk-api-discovery-DvvsdT1z.js} +2 -2
- package/dist/{sdk-api-discovery-DdbqEI70.js.map → sdk-api-discovery-DvvsdT1z.js.map} +1 -1
- package/package.json +5 -5
- package/dist/root-store-CtsStoaR.js.map +0 -1
package/dist/lib/index.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { n as consoleLogAttributes, t as LibraryEarlyConsoleBuffer } from "../early-console-buffer-DMR1SCsN.js";
|
|
2
|
-
import {
|
|
2
|
+
import { C as iframeMessageHandler, E as isEditMode, S as getParentOrigin, T as sendMessageImmediately, _ as generateId, a as tracker, b as editorBridge, c as resolveById, d as useSuperblocksContext, f as useSuperblocksDataTags, g as embedStore, h as useSuperblocksUser, i as getContextFromTraceHeaders, l as SuperblocksContextProvider, m as useSuperblocksProfiles, n as root_store_default, o as addNewPromise, p as useSuperblocksGroups, r as createIframeSpan, s as rejectById, t as ORCHESTRATOR_EXECUTE_RESPONSE_SIZE_LIMIT_FLAG, u as getAppMode, v as sendNotification, w as isEmbeddedBySuperblocksFirstParty, x as getEditStore, y as colors } from "../root-store-BYYXPQRA.js";
|
|
3
3
|
import { n as initTracerProviderWithOrigin } from "../utils-DXaAwgS_.js";
|
|
4
|
-
import { r as updateSdkApiSourceCode, t as discoverAndRegisterSdkApis } from "../sdk-api-discovery-
|
|
5
|
-
import { a as FixWithClarkButton, c as ErrorContent, d as ErrorMessage$1, f as ErrorStack, g as StyledClarkIcon, h as SecondaryButton, i as getWidgetRectAnchorName, l as ErrorDetails, m as ErrorTitle, n as useJSXContext, o as ActionsContainer, p as ErrorSummary, r as getWidgetAnchorName, s as ErrorContainer, u as ErrorIconContainer } from "../jsx-wrapper-
|
|
4
|
+
import { r as updateSdkApiSourceCode, t as discoverAndRegisterSdkApis } from "../sdk-api-discovery-DvvsdT1z.js";
|
|
5
|
+
import { a as FixWithClarkButton, c as ErrorContent, d as ErrorMessage$1, f as ErrorStack, g as StyledClarkIcon, h as SecondaryButton, i as getWidgetRectAnchorName, l as ErrorDetails, m as ErrorTitle, n as useJSXContext, o as ActionsContainer, p as ErrorSummary, r as getWidgetAnchorName, s as ErrorContainer, u as ErrorIconContainer } from "../jsx-wrapper-1kyr6-x3.js";
|
|
6
|
+
import { PropsCategory } from "@superblocksteam/library-shared/props";
|
|
6
7
|
import { action, computed, makeAutoObservable, makeObservable, observable, reaction, when } from "mobx";
|
|
7
8
|
import { UNSAFE_DataRouterContext, generatePath, useLocation, useNavigate, useParams, useRouteError } from "react-router";
|
|
8
|
-
import { NATIVE_COMPONENT_TYPES, NO_SELECT_ATTRIBUTE, Property, SELECTOR_ID_ATTRIBUTE, SOURCE_ID_ATTRIBUTE, URL_PARAMS,
|
|
9
|
+
import { NATIVE_COMPONENT_TYPES, NO_SELECT_ATTRIBUTE, Property, SELECTOR_ID_ATTRIBUTE, SOURCE_ID_ATTRIBUTE, URL_PARAMS, getBindingIdentifier, getDevServerAuthorizationRejectionReason, hasCompactJwtShape } from "@superblocksteam/library-shared";
|
|
9
10
|
import * as React$1 from "react";
|
|
10
11
|
import React, { Suspense, createElement, useCallback, useContext, useEffect, useMemo, useRef, useState } from "react";
|
|
11
12
|
import { isEqual } from "lodash";
|
|
@@ -239,6 +240,324 @@ function installDynamicImportErrorReporter(options = {}) {
|
|
|
239
240
|
};
|
|
240
241
|
}
|
|
241
242
|
//#endregion
|
|
243
|
+
//#region src/lib/user-facing/properties-panel/props-builder.ts
|
|
244
|
+
var Section = class Section {
|
|
245
|
+
props = {};
|
|
246
|
+
propertiesPanelConfig = {};
|
|
247
|
+
constructor(category) {
|
|
248
|
+
this.category = category;
|
|
249
|
+
}
|
|
250
|
+
static category(category) {
|
|
251
|
+
return new Section(category);
|
|
252
|
+
}
|
|
253
|
+
children(props) {
|
|
254
|
+
if (props instanceof CompositeProp || props instanceof RecordProp) this.props = {
|
|
255
|
+
...this.props,
|
|
256
|
+
...props.getProps()
|
|
257
|
+
};
|
|
258
|
+
else if (props instanceof UnionProp) this.props = {
|
|
259
|
+
...this.props,
|
|
260
|
+
...props.getProps()
|
|
261
|
+
};
|
|
262
|
+
else this.props = {
|
|
263
|
+
...this.props,
|
|
264
|
+
...props
|
|
265
|
+
};
|
|
266
|
+
return this;
|
|
267
|
+
}
|
|
268
|
+
add = this.children;
|
|
269
|
+
/** @deprecated Panel configuration is accepted for source compatibility and ignored. */
|
|
270
|
+
propertiesPanel(_config) {
|
|
271
|
+
return this;
|
|
272
|
+
}
|
|
273
|
+
get name() {
|
|
274
|
+
switch (this.category) {
|
|
275
|
+
case PropsCategory.Content: return "Content";
|
|
276
|
+
case PropsCategory.Routing: return "Routing";
|
|
277
|
+
case PropsCategory.Interaction: return "Interaction";
|
|
278
|
+
case PropsCategory.Layout: return "Layout";
|
|
279
|
+
case PropsCategory.Appearance: return "Appearance";
|
|
280
|
+
case PropsCategory.Permissions: return "Permissions";
|
|
281
|
+
case PropsCategory.EventHandlers: return "Actions";
|
|
282
|
+
case PropsCategory.Styles: return "Styles";
|
|
283
|
+
default: return "Uncategorized";
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
};
|
|
287
|
+
var Prop = class Prop {
|
|
288
|
+
prop;
|
|
289
|
+
constructor(typeString) {
|
|
290
|
+
this.prop = {
|
|
291
|
+
path: "",
|
|
292
|
+
dataType: typeString
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
static unset() {
|
|
296
|
+
return new Prop("any");
|
|
297
|
+
}
|
|
298
|
+
static string() {
|
|
299
|
+
return new Prop("string");
|
|
300
|
+
}
|
|
301
|
+
static number() {
|
|
302
|
+
return new Prop("number");
|
|
303
|
+
}
|
|
304
|
+
static boolean() {
|
|
305
|
+
return new Prop("boolean");
|
|
306
|
+
}
|
|
307
|
+
static array() {
|
|
308
|
+
return new Prop("array");
|
|
309
|
+
}
|
|
310
|
+
static any() {
|
|
311
|
+
return new Prop("any");
|
|
312
|
+
}
|
|
313
|
+
static jsx() {
|
|
314
|
+
return new Prop("jsx");
|
|
315
|
+
}
|
|
316
|
+
static literal(value) {
|
|
317
|
+
switch (typeof value) {
|
|
318
|
+
case "string": return Prop.string().default(value);
|
|
319
|
+
case "number": return Prop.number().default(value);
|
|
320
|
+
case "boolean": return Prop.boolean().default(value);
|
|
321
|
+
default: throw new Error(`Invalid literal value: ${value}`);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
static eventHandler() {
|
|
325
|
+
return new Prop("eventHandler");
|
|
326
|
+
}
|
|
327
|
+
static function(implementation) {
|
|
328
|
+
return new FunctionProp(implementation);
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* Creates a composite property, which is a property that contains nested properties. For example,
|
|
332
|
+
* the following composite property:
|
|
333
|
+
*
|
|
334
|
+
* ```ts
|
|
335
|
+
* const prop = Prop.composite({
|
|
336
|
+
* name: Prop.string(),
|
|
337
|
+
* age: Prop.number(),
|
|
338
|
+
* });
|
|
339
|
+
* ```
|
|
340
|
+
*
|
|
341
|
+
* is equivalent to the following type:
|
|
342
|
+
*
|
|
343
|
+
* ```ts
|
|
344
|
+
* type Prop = {
|
|
345
|
+
* name: string;
|
|
346
|
+
* age: number;
|
|
347
|
+
* };
|
|
348
|
+
* ```
|
|
349
|
+
*/
|
|
350
|
+
static composite(props) {
|
|
351
|
+
return new CompositeProp(props);
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Creates a record property, which is a record that maps string keys to the nestedproperties. For example,
|
|
355
|
+
* the following record property:
|
|
356
|
+
*
|
|
357
|
+
* ```ts
|
|
358
|
+
* const prop = Prop.record({
|
|
359
|
+
* name: Prop.string(),
|
|
360
|
+
* age: Prop.number(),
|
|
361
|
+
* });
|
|
362
|
+
* ```
|
|
363
|
+
*
|
|
364
|
+
* is equivalent to the following type:
|
|
365
|
+
*
|
|
366
|
+
* ```ts
|
|
367
|
+
* type Prop = Record<string, {
|
|
368
|
+
* name: string;
|
|
369
|
+
* age: number;
|
|
370
|
+
* }>;
|
|
371
|
+
* ```
|
|
372
|
+
*/
|
|
373
|
+
static record(props) {
|
|
374
|
+
return new RecordProp(props);
|
|
375
|
+
}
|
|
376
|
+
static union(props) {
|
|
377
|
+
return new UnionProp(props.shared, props.variants);
|
|
378
|
+
}
|
|
379
|
+
default(de) {
|
|
380
|
+
this.prop.default = de;
|
|
381
|
+
return this;
|
|
382
|
+
}
|
|
383
|
+
contextual(computedArgs) {
|
|
384
|
+
this.prop.contextual = true;
|
|
385
|
+
this.prop.computedArgs = computedArgs;
|
|
386
|
+
return this;
|
|
387
|
+
}
|
|
388
|
+
setName(name) {
|
|
389
|
+
this.prop.path = name;
|
|
390
|
+
return this;
|
|
391
|
+
}
|
|
392
|
+
/** @deprecated Panel configuration is accepted for source compatibility and ignored. */
|
|
393
|
+
propertiesPanel(_schema) {
|
|
394
|
+
return this;
|
|
395
|
+
}
|
|
396
|
+
/** @deprecated Panel metadata is accepted for source compatibility and ignored. */
|
|
397
|
+
setDisplayProperty(_property, _value) {
|
|
398
|
+
return this;
|
|
399
|
+
}
|
|
400
|
+
/** @deprecated Panel relations are accepted for source compatibility and ignored. */
|
|
401
|
+
dependsOn(_relations) {
|
|
402
|
+
return this;
|
|
403
|
+
}
|
|
404
|
+
getRelations() {
|
|
405
|
+
return [];
|
|
406
|
+
}
|
|
407
|
+
hasPropertiesPanelDisplay() {
|
|
408
|
+
return false;
|
|
409
|
+
}
|
|
410
|
+
toDefinition(_props) {}
|
|
411
|
+
docs(docs) {
|
|
412
|
+
this.prop.docs = docs;
|
|
413
|
+
return this;
|
|
414
|
+
}
|
|
415
|
+
build() {
|
|
416
|
+
return this.prop;
|
|
417
|
+
}
|
|
418
|
+
get type() {
|
|
419
|
+
return this.prop.dataType;
|
|
420
|
+
}
|
|
421
|
+
get path() {
|
|
422
|
+
return this.prop.path;
|
|
423
|
+
}
|
|
424
|
+
};
|
|
425
|
+
/**
|
|
426
|
+
* See {@link Prop.composite}
|
|
427
|
+
*/
|
|
428
|
+
var CompositeProp = class extends Prop {
|
|
429
|
+
typeString = "composite";
|
|
430
|
+
nestedProps;
|
|
431
|
+
constructor(props) {
|
|
432
|
+
super("composite");
|
|
433
|
+
this.nestedProps = props;
|
|
434
|
+
}
|
|
435
|
+
getProps() {
|
|
436
|
+
return this.nestedProps;
|
|
437
|
+
}
|
|
438
|
+
propertiesPanelChildrenDisplayMode() {}
|
|
439
|
+
};
|
|
440
|
+
/**
|
|
441
|
+
* See {@link Prop.record}
|
|
442
|
+
*/
|
|
443
|
+
var RecordProp = class extends Prop {
|
|
444
|
+
typeString = "recordOf";
|
|
445
|
+
nestedProps;
|
|
446
|
+
constructor(props) {
|
|
447
|
+
super("recordOf");
|
|
448
|
+
this.nestedProps = props;
|
|
449
|
+
}
|
|
450
|
+
getProps() {
|
|
451
|
+
return this.nestedProps;
|
|
452
|
+
}
|
|
453
|
+
};
|
|
454
|
+
var FunctionProp = class extends Prop {
|
|
455
|
+
typeString = "function";
|
|
456
|
+
constructor(implementation) {
|
|
457
|
+
super("function");
|
|
458
|
+
this.default(implementation);
|
|
459
|
+
}
|
|
460
|
+
/** @deprecated Action panel metadata is accepted for source compatibility and ignored. */
|
|
461
|
+
actionPanel(_panel) {
|
|
462
|
+
return this;
|
|
463
|
+
}
|
|
464
|
+
getActionPanel() {}
|
|
465
|
+
};
|
|
466
|
+
var UnionProp = class extends Prop {
|
|
467
|
+
typeString = "union";
|
|
468
|
+
shared;
|
|
469
|
+
variants;
|
|
470
|
+
constructor(shared, variants) {
|
|
471
|
+
super("any");
|
|
472
|
+
this.shared = shared;
|
|
473
|
+
this.variants = variants;
|
|
474
|
+
}
|
|
475
|
+
getProps() {
|
|
476
|
+
const props = { ...this.shared };
|
|
477
|
+
for (const variant of this.variants) for (const [key, prop] of Object.entries(variant)) if (!Object.hasOwn(props, key)) props[key] = prop;
|
|
478
|
+
return props;
|
|
479
|
+
}
|
|
480
|
+
};
|
|
481
|
+
function buildCompositeDefault(prop, name, parentDefault) {
|
|
482
|
+
const defaultThroughParent = parentDefault?.[name];
|
|
483
|
+
const selfDefault = prop.build().default;
|
|
484
|
+
let propDefault = defaultThroughParent ?? selfDefault;
|
|
485
|
+
if (!propDefault && typeof parentDefault === "function") propDefault = function getNestedDefault(s) {
|
|
486
|
+
return parentDefault.call(this, s)?.[name];
|
|
487
|
+
};
|
|
488
|
+
return propDefault;
|
|
489
|
+
}
|
|
490
|
+
function buildPropLeafDefault(prop, name, parentDefault) {
|
|
491
|
+
const defaultThroughParent = parentDefault?.[name];
|
|
492
|
+
let propDefault = prop.build().default ?? defaultThroughParent;
|
|
493
|
+
if (!propDefault && typeof parentDefault === "function") propDefault = function getNestedDefault(s) {
|
|
494
|
+
return parentDefault.call(this, s)?.[name];
|
|
495
|
+
};
|
|
496
|
+
return propDefault;
|
|
497
|
+
}
|
|
498
|
+
/**
|
|
499
|
+
* Core traversal function that walks through all properties in sections
|
|
500
|
+
* and calls the provided callback for each leaf property.
|
|
501
|
+
*/
|
|
502
|
+
function traverseProps(sections, onProp, parentPath = "") {
|
|
503
|
+
const processProps = ({ props, parentPath, parentDefault }) => {
|
|
504
|
+
for (const [name, prop] of Object.entries(props)) {
|
|
505
|
+
if (!prop) continue;
|
|
506
|
+
const fullPath = parentPath ? `${parentPath}.${name}` : name;
|
|
507
|
+
if (prop instanceof CompositeProp) {
|
|
508
|
+
const compositeDefault = buildCompositeDefault(prop, name, parentDefault);
|
|
509
|
+
processProps({
|
|
510
|
+
props: prop.nestedProps,
|
|
511
|
+
parentPath: fullPath,
|
|
512
|
+
parentDefault: compositeDefault
|
|
513
|
+
});
|
|
514
|
+
} else if (prop instanceof RecordProp) {
|
|
515
|
+
const recordPath = `${fullPath}.*`;
|
|
516
|
+
processProps({
|
|
517
|
+
props: prop.nestedProps,
|
|
518
|
+
parentPath: recordPath,
|
|
519
|
+
parentDefault: prop.build().default
|
|
520
|
+
});
|
|
521
|
+
} else if (prop instanceof Section) processProps({
|
|
522
|
+
props: prop.props,
|
|
523
|
+
parentPath
|
|
524
|
+
});
|
|
525
|
+
else if (prop instanceof UnionProp) {
|
|
526
|
+
const sharedKeys = Object.keys(prop.shared);
|
|
527
|
+
processProps({
|
|
528
|
+
props: prop.shared,
|
|
529
|
+
parentPath: fullPath
|
|
530
|
+
});
|
|
531
|
+
for (const variant of prop.variants) processProps({
|
|
532
|
+
props: Object.fromEntries(Object.entries(variant).filter(([key]) => !sharedKeys.includes(key))),
|
|
533
|
+
parentPath: fullPath
|
|
534
|
+
});
|
|
535
|
+
} else if (prop instanceof Prop) onProp(prop, fullPath, name, parentDefault);
|
|
536
|
+
else console.warn("Invalid prop type", {
|
|
537
|
+
name,
|
|
538
|
+
prop
|
|
539
|
+
});
|
|
540
|
+
}
|
|
541
|
+
};
|
|
542
|
+
for (const section of Object.values(sections)) processProps({
|
|
543
|
+
props: section.props,
|
|
544
|
+
parentPath,
|
|
545
|
+
parentDefault: void 0
|
|
546
|
+
});
|
|
547
|
+
}
|
|
548
|
+
function createManagedPropsList(sections, parentPath = "") {
|
|
549
|
+
const managedPropsList = [];
|
|
550
|
+
traverseProps(sections, (prop, fullPath, name, parentDefault) => {
|
|
551
|
+
let configuredProp = prop.setName(fullPath);
|
|
552
|
+
const propDefault = buildPropLeafDefault(prop, name, parentDefault);
|
|
553
|
+
if (propDefault !== void 0) configuredProp = configuredProp.default(propDefault);
|
|
554
|
+
const builtProp = configuredProp.build();
|
|
555
|
+
if (builtProp.dataType === "internal") return;
|
|
556
|
+
managedPropsList.push({ ...builtProp });
|
|
557
|
+
}, parentPath);
|
|
558
|
+
return managedPropsList;
|
|
559
|
+
}
|
|
560
|
+
//#endregion
|
|
242
561
|
//#region src/lib/internal-details/sb-wrapper.tsx
|
|
243
562
|
/**
|
|
244
563
|
* Register a component to be used with the framework.
|
|
@@ -261,15 +580,7 @@ const registerComponentInternal = (Component, propertiesDefinition) => {
|
|
|
261
580
|
root_store_default.componentRegistry.addEditorConfig(type, defaultEditorConfig);
|
|
262
581
|
}
|
|
263
582
|
const chainableComponent = {
|
|
264
|
-
addEditorTemplate: (
|
|
265
|
-
const catalog = templateConfig.catalog ?? {
|
|
266
|
-
displayName: type,
|
|
267
|
-
category: "MISC"
|
|
268
|
-
};
|
|
269
|
-
root_store_default.componentRegistry.addEditorTemplate(type, {
|
|
270
|
-
...templateConfig,
|
|
271
|
-
catalog
|
|
272
|
-
});
|
|
583
|
+
addEditorTemplate: (_templateConfig) => {
|
|
273
584
|
return chainableComponent;
|
|
274
585
|
},
|
|
275
586
|
editorConfig: (config) => {
|
|
@@ -1779,6 +2090,46 @@ function BuildErrorModal({ isOpen, error, onClose }) {
|
|
|
1779
2090
|
});
|
|
1780
2091
|
}
|
|
1781
2092
|
//#endregion
|
|
2093
|
+
//#region src/edit-mode/dev-server-token-delivery.ts
|
|
2094
|
+
/**
|
|
2095
|
+
* Socket identity and pod TokenManager delivery are different stores.
|
|
2096
|
+
* `updateAuthorization` only reports whether the iframe socket changed;
|
|
2097
|
+
* this tracker decides whether `/_sb_update_token` still needs to run.
|
|
2098
|
+
*/
|
|
2099
|
+
function createDevServerTokenDelivery() {
|
|
2100
|
+
let deliveredAuthorization;
|
|
2101
|
+
let inFlightAuthorization;
|
|
2102
|
+
return {
|
|
2103
|
+
decide(authorizationChanged, installedAuthorization) {
|
|
2104
|
+
if (!installedAuthorization) return authorizationChanged ? { action: "abort" } : { action: "skip" };
|
|
2105
|
+
if (!authorizationChanged) {
|
|
2106
|
+
if (installedAuthorization === inFlightAuthorization || installedAuthorization === deliveredAuthorization) return { action: "skip" };
|
|
2107
|
+
return {
|
|
2108
|
+
action: "post",
|
|
2109
|
+
abortInFlight: false
|
|
2110
|
+
};
|
|
2111
|
+
}
|
|
2112
|
+
return {
|
|
2113
|
+
action: "post",
|
|
2114
|
+
abortInFlight: true
|
|
2115
|
+
};
|
|
2116
|
+
},
|
|
2117
|
+
markAborted() {
|
|
2118
|
+
inFlightAuthorization = void 0;
|
|
2119
|
+
},
|
|
2120
|
+
markDelivered(authorization) {
|
|
2121
|
+
deliveredAuthorization = authorization;
|
|
2122
|
+
if (inFlightAuthorization === authorization) inFlightAuthorization = void 0;
|
|
2123
|
+
},
|
|
2124
|
+
markFailed(authorization) {
|
|
2125
|
+
if (inFlightAuthorization === authorization) inFlightAuthorization = void 0;
|
|
2126
|
+
},
|
|
2127
|
+
markStarted(authorization) {
|
|
2128
|
+
inFlightAuthorization = authorization;
|
|
2129
|
+
}
|
|
2130
|
+
};
|
|
2131
|
+
}
|
|
2132
|
+
//#endregion
|
|
1782
2133
|
//#region src/edit-mode/features/ai-store.ts
|
|
1783
2134
|
var AiManager = class {
|
|
1784
2135
|
_isTaggingEnabled = true;
|
|
@@ -1954,7 +2305,7 @@ var AsyncSocket = class {
|
|
|
1954
2305
|
//#region src/edit-mode/authorization-metrics.ts
|
|
1955
2306
|
let devServerAuthorizationEvents;
|
|
1956
2307
|
function recordDevServerAuthorizationEvent(event, attributes) {
|
|
1957
|
-
if (!devServerAuthorizationEvents) devServerAuthorizationEvents = metrics.getMeter("superblocks-library").createCounter("dev_server_authorization_events_total", { description: "Count of dev-server authorization compatibility, rejection, and retry-exhaustion events" });
|
|
2308
|
+
if (!devServerAuthorizationEvents) devServerAuthorizationEvents = metrics.getMeter("superblocks-library").createCounter("dev_server_authorization_events_total", { description: "Count of dev-server authorization compatibility, rejection, refresh, and retry-exhaustion events" });
|
|
1958
2309
|
devServerAuthorizationEvents.add(1, {
|
|
1959
2310
|
event,
|
|
1960
2311
|
...attributes
|
|
@@ -2128,23 +2479,37 @@ var OperationAPI = class {
|
|
|
2128
2479
|
/**
|
|
2129
2480
|
* Updates the authorization token for the socket connection.
|
|
2130
2481
|
* This is called when the token is refreshed in the parent window.
|
|
2482
|
+
* Returns true only when the installed authorization changes.
|
|
2131
2483
|
*/
|
|
2132
2484
|
updateAuthorization(newAuthorization, { allowLegacyAuthorization } = {}) {
|
|
2485
|
+
const revokesInstalledLegacyAuthorization = allowLegacyAuthorization === false && this.currentAuthorizationAllowsLegacy;
|
|
2486
|
+
if (newAuthorization === this.currentAuthorization && !revokesInstalledLegacyAuthorization) return false;
|
|
2133
2487
|
const rejectionReason = newAuthorization ? getDevServerAuthorizationRejectionReason(newAuthorization, this.applicationId) : void 0;
|
|
2134
2488
|
const acceptsLegacyAuthorization = newAuthorization !== void 0 && rejectionReason !== void 0 && (allowLegacyAuthorization ?? this.currentAuthorizationAllowsLegacy) && isUnexpiredLegacyAuthorization(newAuthorization) && (!this.currentAuthorization || !isDevServerAuthorization(this.currentAuthorization, this.applicationId));
|
|
2135
2489
|
if (allowLegacyAuthorization === false) this.currentAuthorizationAllowsLegacy = false;
|
|
2136
2490
|
if (newAuthorization === void 0 && allowLegacyAuthorization === false && this.currentAuthorization && isDevServerAuthorization(this.currentAuthorization, this.applicationId)) return false;
|
|
2137
2491
|
if (newAuthorization && rejectionReason !== void 0 && !acceptsLegacyAuthorization) {
|
|
2492
|
+
let authorizationChanged = false;
|
|
2138
2493
|
recordDevServerAuthorizationEvent("authorization_rejected", { reason: rejectionReason });
|
|
2139
2494
|
if (this.currentAuthorization && !this.currentAuthorizationAllowsLegacy && !isDevServerAuthorization(this.currentAuthorization, this.applicationId)) {
|
|
2140
2495
|
this.currentAuthorization = void 0;
|
|
2141
2496
|
this.currentAuthorizationAllowsLegacy = false;
|
|
2142
2497
|
this.isocket?.setAuthorization(void 0);
|
|
2498
|
+
authorizationChanged = true;
|
|
2143
2499
|
}
|
|
2144
2500
|
console.warn("[internal] [OperationAPI] Ignoring invalid dev server authorization", consoleLogAttributes({
|
|
2145
2501
|
"application.id": this.applicationId,
|
|
2146
2502
|
"error.type": rejectionReason
|
|
2147
2503
|
}));
|
|
2504
|
+
return authorizationChanged;
|
|
2505
|
+
}
|
|
2506
|
+
if (newAuthorization !== void 0 && rejectionReason === void 0 && this.applicationId !== void 0 && !shouldUseAuthorizationCandidate(this.currentAuthorization, newAuthorization, this.applicationId)) {
|
|
2507
|
+
recordDevServerAuthorizationEvent("authorization_downgrade_ignored");
|
|
2508
|
+
console.warn("[internal] [OperationAPI] Ignoring older dev server authorization", consoleLogAttributes({
|
|
2509
|
+
"application.id": this.applicationId,
|
|
2510
|
+
"authorization.candidate_expiration_ms": getAuthorizationExpirationMs(newAuthorization),
|
|
2511
|
+
"authorization.installed_expiration_ms": getAuthorizationExpirationMs(this.currentAuthorization)
|
|
2512
|
+
}));
|
|
2148
2513
|
return false;
|
|
2149
2514
|
}
|
|
2150
2515
|
if (acceptsLegacyAuthorization) recordDevServerAuthorizationEvent("legacy_authorization_accepted");
|
|
@@ -2157,6 +2522,9 @@ var OperationAPI = class {
|
|
|
2157
2522
|
} else console.warn("[internal] [OperationAPI] Cannot update authorization: socket not yet initialized");
|
|
2158
2523
|
return true;
|
|
2159
2524
|
}
|
|
2525
|
+
getCurrentAuthorization() {
|
|
2526
|
+
return this.currentAuthorization;
|
|
2527
|
+
}
|
|
2160
2528
|
handleAuthorizationFailure(error, { applicationId, connectionStartTime, connectionTarget, connectionType }) {
|
|
2161
2529
|
if (this.authorizationRefreshApplicationId !== applicationId) {
|
|
2162
2530
|
this.resetAuthorizationRefresh();
|
|
@@ -2453,161 +2821,19 @@ async function connectSocket(serverUrl, { peerId, userId, applicationId, getAuth
|
|
|
2453
2821
|
//#endregion
|
|
2454
2822
|
//#region src/edit-mode/features/operation-store.ts
|
|
2455
2823
|
var OperationManager = class {
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
batchOperationTransactionId;
|
|
2460
|
-
visibleSourceIds = [];
|
|
2461
|
-
constructor() {
|
|
2462
|
-
makeAutoObservable(this);
|
|
2463
|
-
}
|
|
2464
|
-
get allPendingTransactions() {
|
|
2465
|
-
return this.pendingTransactions;
|
|
2466
|
-
}
|
|
2467
|
-
get pendingDeleteOperations() {
|
|
2468
|
-
return this.pendingTransactions.filter((t) => t.type === "editor:deleteComponents");
|
|
2469
|
-
}
|
|
2470
|
-
get hasPendingOperations() {
|
|
2471
|
-
return this.pendingTransactions.length > 0;
|
|
2472
|
-
}
|
|
2473
|
-
get allNames() {
|
|
2474
|
-
return [];
|
|
2475
|
-
}
|
|
2476
|
-
@action executeOrAddToBatch(operation, addTransaction = true) {
|
|
2477
|
-
const transactionId = this.batchOperationTransactionId ?? generateId();
|
|
2478
|
-
const payload = this.waitingForBatch ? operation.payload : {
|
|
2479
|
-
...operation.payload,
|
|
2824
|
+
deleteComponents(sourceIds) {
|
|
2825
|
+
editorBridge.editOpRequest("editor:deleteComponents", {
|
|
2826
|
+
elements: sourceIds.map((sourceId) => ({ source: { id: sourceId } })),
|
|
2480
2827
|
transaction: {
|
|
2481
|
-
id:
|
|
2828
|
+
id: generateId(),
|
|
2482
2829
|
origin: "LIBRARY"
|
|
2483
2830
|
}
|
|
2484
|
-
};
|
|
2485
|
-
const opWithId = {
|
|
2486
|
-
...operation,
|
|
2487
|
-
id: transactionId,
|
|
2488
|
-
payload
|
|
2489
|
-
};
|
|
2490
|
-
if (addTransaction) this.addPendingTransaction(opWithId);
|
|
2491
|
-
if (this.waitingForBatch) this.batchOperations.push(opWithId);
|
|
2492
|
-
else switch (operation.type) {
|
|
2493
|
-
case "editor:moveComponent": return editorBridge.editOpRequest("editor:moveComponent", payload);
|
|
2494
|
-
case "editor:createComponent": return editorBridge.editOpRequest("editor:createComponent", payload);
|
|
2495
|
-
case "editor:deleteComponents": return editorBridge.editOpRequest("editor:deleteComponents", payload);
|
|
2496
|
-
}
|
|
2497
|
-
}
|
|
2498
|
-
@action addPendingTransaction(transaction) {
|
|
2499
|
-
this.pendingTransactions.push(transaction);
|
|
2500
|
-
}
|
|
2501
|
-
@action clearPendingTransactions(transactionIds) {
|
|
2502
|
-
const toClear = new Set(transactionIds);
|
|
2503
|
-
const { cleared, remaining } = this.pendingTransactions.reduce((acc, transaction) => {
|
|
2504
|
-
if (toClear.has(transaction.id)) acc.cleared.push(transaction);
|
|
2505
|
-
else acc.remaining.push(transaction);
|
|
2506
|
-
return acc;
|
|
2507
|
-
}, {
|
|
2508
|
-
cleared: [],
|
|
2509
|
-
remaining: []
|
|
2510
|
-
});
|
|
2511
|
-
this.pendingTransactions = remaining;
|
|
2512
|
-
cleared.forEach((transaction) => {
|
|
2513
|
-
if (transaction.callback) transaction.callback();
|
|
2514
2831
|
});
|
|
2515
2832
|
}
|
|
2516
|
-
|
|
2517
|
-
this.waitingForBatch = true;
|
|
2518
|
-
this.batchOperationTransactionId = generateId();
|
|
2519
|
-
performOperations();
|
|
2520
|
-
editorBridge.editOpRequest("editor:batchUpdate", {
|
|
2521
|
-
updates: this.batchOperations.map((op) => ({
|
|
2522
|
-
type: op.type,
|
|
2523
|
-
payload: op.payload
|
|
2524
|
-
})),
|
|
2525
|
-
transaction: {
|
|
2526
|
-
origin: "LIBRARY",
|
|
2527
|
-
id: this.batchOperationTransactionId
|
|
2528
|
-
}
|
|
2529
|
-
});
|
|
2530
|
-
this.waitingForBatch = false;
|
|
2531
|
-
this.batchOperations = [];
|
|
2532
|
-
this.batchOperationTransactionId = void 0;
|
|
2533
|
-
}
|
|
2534
|
-
@action createComponent(payload) {
|
|
2535
|
-
this.executeOrAddToBatch({
|
|
2536
|
-
type: "editor:createComponent",
|
|
2537
|
-
payload
|
|
2538
|
-
});
|
|
2539
|
-
}
|
|
2540
|
-
@action dropComponent(action) {
|
|
2541
|
-
const { from, to, propsToChange } = action;
|
|
2542
|
-
const payload = {
|
|
2543
|
-
from,
|
|
2544
|
-
to,
|
|
2545
|
-
changedProps: propsToChange ?? {}
|
|
2546
|
-
};
|
|
2547
|
-
this.executeOrAddToBatch({
|
|
2548
|
-
type: "editor:moveComponent",
|
|
2549
|
-
payload
|
|
2550
|
-
});
|
|
2551
|
-
}
|
|
2552
|
-
@action deleteComponents(sourceIds) {
|
|
2553
|
-
const payload = { elements: sourceIds.map((sourceId) => ({ source: { id: sourceId } })) };
|
|
2554
|
-
this.executeOrAddToBatch({
|
|
2555
|
-
type: "editor:deleteComponents",
|
|
2556
|
-
payload
|
|
2557
|
-
}, false);
|
|
2558
|
-
}
|
|
2559
|
-
acknowledgeEditOperation(operation) {
|
|
2560
|
-
if (!("transaction" in operation.payload) || !operation.payload.transaction?.id) {
|
|
2561
|
-
console.error("No transaction id in edit operation", operation);
|
|
2562
|
-
return;
|
|
2563
|
-
}
|
|
2564
|
-
const addOperation = (operation, batchTransactionId) => {
|
|
2565
|
-
switch (operation.type) {
|
|
2566
|
-
case "editor:createComponent": {
|
|
2567
|
-
const { type, payload } = operation;
|
|
2568
|
-
this.addPendingTransaction({
|
|
2569
|
-
type,
|
|
2570
|
-
id: batchTransactionId ?? payload.transaction.id,
|
|
2571
|
-
payload
|
|
2572
|
-
});
|
|
2573
|
-
break;
|
|
2574
|
-
}
|
|
2575
|
-
case "editor:deleteComponents": {
|
|
2576
|
-
const { type, payload } = operation;
|
|
2577
|
-
this.addPendingTransaction({
|
|
2578
|
-
type,
|
|
2579
|
-
id: batchTransactionId ?? payload.transaction.id,
|
|
2580
|
-
payload
|
|
2581
|
-
});
|
|
2582
|
-
break;
|
|
2583
|
-
}
|
|
2584
|
-
case "editor:moveComponent": {
|
|
2585
|
-
const { type, payload } = operation;
|
|
2586
|
-
this.addPendingTransaction({
|
|
2587
|
-
type,
|
|
2588
|
-
id: batchTransactionId ?? payload.transaction.id,
|
|
2589
|
-
payload
|
|
2590
|
-
});
|
|
2591
|
-
break;
|
|
2592
|
-
}
|
|
2593
|
-
default: console.error("Unknown edit operation", operation);
|
|
2594
|
-
}
|
|
2595
|
-
};
|
|
2596
|
-
if (operation.type === "editor:batchUpdate") {
|
|
2597
|
-
const { payload } = operation;
|
|
2598
|
-
if (!payload.transaction?.id) {
|
|
2599
|
-
console.error("No transaction id in batch", operation);
|
|
2600
|
-
return;
|
|
2601
|
-
}
|
|
2602
|
-
for (const update of payload.updates) addOperation(update, payload.transaction.id);
|
|
2603
|
-
} else addOperation(operation);
|
|
2604
|
-
}
|
|
2833
|
+
acknowledgeEditOperation(_operation) {}
|
|
2605
2834
|
async ensureFilesSynced() {
|
|
2606
2835
|
await source_update_api_default.ensureFilesSynced();
|
|
2607
2836
|
}
|
|
2608
|
-
generateSourceId() {
|
|
2609
|
-
return generateSourceId();
|
|
2610
|
-
}
|
|
2611
2837
|
};
|
|
2612
2838
|
//#endregion
|
|
2613
2839
|
//#region src/edit-mode/runtime-graph/observable-graph.ts
|
|
@@ -2654,7 +2880,6 @@ var RuntimeComponentNode = class {
|
|
|
2654
2880
|
isSbComponent;
|
|
2655
2881
|
isHtmlElement;
|
|
2656
2882
|
noSelect;
|
|
2657
|
-
props;
|
|
2658
2883
|
constructor(store, params) {
|
|
2659
2884
|
this.store = store;
|
|
2660
2885
|
this.sourceId = params.sourceId;
|
|
@@ -2663,10 +2888,7 @@ var RuntimeComponentNode = class {
|
|
|
2663
2888
|
this.isSbComponent = params.isSbComponent;
|
|
2664
2889
|
this.isHtmlElement = params.isHtmlElement;
|
|
2665
2890
|
this.noSelect = params.noSelect;
|
|
2666
|
-
makeAutoObservable(this, {
|
|
2667
|
-
type: observable.ref,
|
|
2668
|
-
props: observable.ref
|
|
2669
|
-
});
|
|
2891
|
+
makeAutoObservable(this, { type: observable.ref });
|
|
2670
2892
|
}
|
|
2671
2893
|
get firstRenderedTag() {
|
|
2672
2894
|
if (this?.isHtmlElement) return this.selectorId;
|
|
@@ -2757,13 +2979,9 @@ var RuntimeTrackingStore = class {
|
|
|
2757
2979
|
}
|
|
2758
2980
|
return this.jsxNodes[selectorId]?.nearestSelectableAncestor;
|
|
2759
2981
|
}
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
componentNode.props = props;
|
|
2764
|
-
if (props.disabled) this.disabledComponents.add(selectorId);
|
|
2765
|
-
else this.disabledComponents.delete(selectorId);
|
|
2766
|
-
}
|
|
2982
|
+
setComponentDisabled(selectorId, disabled) {
|
|
2983
|
+
if (this.jsxNodes[selectorId]) if (disabled) this.disabledComponents.add(selectorId);
|
|
2984
|
+
else this.disabledComponents.delete(selectorId);
|
|
2767
2985
|
}
|
|
2768
2986
|
getComponent(selectorId) {
|
|
2769
2987
|
return this.jsxNodes[selectorId];
|
|
@@ -4211,6 +4429,7 @@ if (isEditMode()) {
|
|
|
4211
4429
|
let tokenUpdateGeneration = 0;
|
|
4212
4430
|
let tokenUpdateAbortController = null;
|
|
4213
4431
|
let devServerTokenUpdateQueue = Promise.resolve();
|
|
4432
|
+
const tokenDelivery = createDevServerTokenDelivery();
|
|
4214
4433
|
const postDevServerAuthorization = async (authorization, generation, signal) => {
|
|
4215
4434
|
const maxAttempts = 3;
|
|
4216
4435
|
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
@@ -4222,11 +4441,15 @@ if (isEditMode()) {
|
|
|
4222
4441
|
signal
|
|
4223
4442
|
});
|
|
4224
4443
|
if (generation !== tokenUpdateGeneration) return;
|
|
4225
|
-
if (response.ok)
|
|
4444
|
+
if (response.ok) {
|
|
4445
|
+
tokenDelivery.markDelivered(authorization);
|
|
4446
|
+
return;
|
|
4447
|
+
}
|
|
4226
4448
|
throw new Error(`status ${response.status}`);
|
|
4227
4449
|
} catch (error) {
|
|
4228
4450
|
if (generation !== tokenUpdateGeneration) return;
|
|
4229
4451
|
if (attempt === maxAttempts) {
|
|
4452
|
+
tokenDelivery.markFailed(authorization);
|
|
4230
4453
|
console.warn("[internal] [iframe-wrappers] failed to update dev-server token", error);
|
|
4231
4454
|
return;
|
|
4232
4455
|
}
|
|
@@ -4235,13 +4458,20 @@ if (isEditMode()) {
|
|
|
4235
4458
|
}
|
|
4236
4459
|
};
|
|
4237
4460
|
const updateDevServerAuthorization = (authorization, allowLegacyAuthorization) => {
|
|
4238
|
-
|
|
4461
|
+
const authorizationChanged = source_update_api_default.updateAuthorization(authorization, { allowLegacyAuthorization });
|
|
4462
|
+
const installedAuthorization = source_update_api_default.getCurrentAuthorization();
|
|
4463
|
+
const decision = tokenDelivery.decide(authorizationChanged, installedAuthorization);
|
|
4464
|
+
if (decision.action === "skip") return;
|
|
4239
4465
|
const generation = ++tokenUpdateGeneration;
|
|
4240
|
-
|
|
4241
|
-
|
|
4466
|
+
if (decision.action !== "post" || decision.abortInFlight) {
|
|
4467
|
+
tokenUpdateAbortController?.abort();
|
|
4468
|
+
tokenDelivery.markAborted();
|
|
4469
|
+
}
|
|
4470
|
+
if (decision.action !== "post" || !installedAuthorization) return;
|
|
4242
4471
|
const abortController = new AbortController();
|
|
4243
4472
|
tokenUpdateAbortController = abortController;
|
|
4244
|
-
|
|
4473
|
+
tokenDelivery.markStarted(installedAuthorization);
|
|
4474
|
+
devServerTokenUpdateQueue = devServerTokenUpdateQueue.catch(() => void 0).then(() => postDevServerAuthorization(installedAuthorization, generation, abortController.signal));
|
|
4245
4475
|
};
|
|
4246
4476
|
const handleTokenUpdate = ({ data }) => {
|
|
4247
4477
|
const { authorization } = data.payload;
|