@cesdk/cesdk-js 1.63.0-rc.3 → 1.63.0-rc.4

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/index.d.ts CHANGED
@@ -3373,6 +3373,182 @@ export declare type ExportSceneAction = (options: {
3373
3373
  * The FeatureAPI allows you to enable or disable specific functionality
3374
3374
  * within the editor based on custom conditions or user permissions.
3375
3375
  *
3376
+ * ## Understanding the Feature System
3377
+ *
3378
+ * The feature system uses a **predicate chain** to determine if a feature is enabled.
3379
+ * There are two types of predicates:
3380
+ *
3381
+ * 1. **Boolean predicates** (e.g., `true` or `false`) - These are **always terminal** and immediately return their value.
3382
+ * 2. **Function predicates** - The implementation decides whether to call `isPreviousEnable()` (continue chain) or return directly (end chain).
3383
+ *
3384
+ * ### Evaluation Order
3385
+ *
3386
+ * Predicates are evaluated in this order:
3387
+ * 1. **`set()` predicates** (most recent first) - Evaluated **FIRST**
3388
+ * 2. **`enable()`/`disable()` state** - Evaluated **LAST**
3389
+ *
3390
+ * This means **`set()` can override `enable()` and `disable()`**.
3391
+ *
3392
+ * ## Common Use Cases and Expected Outcomes
3393
+ *
3394
+ * ### Use Case 1: Simple Enable/Disable
3395
+ *
3396
+ * **Use `enable()` and `disable()` for simple on/off control:**
3397
+ *
3398
+ * ```typescript
3399
+ * // Enable a feature with its default behavior
3400
+ * cesdk.feature.enable('ly.img.delete');
3401
+ * // isEnabled: true
3402
+ *
3403
+ * // Disable it
3404
+ * cesdk.feature.disable('ly.img.delete');
3405
+ * // isEnabled: false
3406
+ *
3407
+ * // Re-enable it
3408
+ * cesdk.feature.enable('ly.img.delete');
3409
+ * // isEnabled: true
3410
+ * ```
3411
+ *
3412
+ * **Expected outcome:** `enable()` and `disable()` work together to toggle features on/off.
3413
+ *
3414
+ * ### Use Case 2: Custom Conditions with `set()`
3415
+ *
3416
+ * **Use `set()` when you need custom logic:**
3417
+ *
3418
+ * ```typescript
3419
+ * // Enable delete only when something is selected
3420
+ * cesdk.feature.set('ly.img.delete', ({ engine }) => {
3421
+ * return engine.block.findAllSelected().length > 0;
3422
+ * });
3423
+ * // isEnabled: depends on selection
3424
+ *
3425
+ * // Now calling disable() won't work because set() is evaluated first!
3426
+ * cesdk.feature.disable('ly.img.delete');
3427
+ * // isEnabled: still depends on selection (disable is ignored)
3428
+ * ```
3429
+ *
3430
+ * **Expected outcome:** `set()` function predicates are evaluated before `disable()`,
3431
+ * so `disable()` has no effect when a `set()` predicate exists.
3432
+ *
3433
+ * ### Use Case 3: Terminal Boolean Predicates
3434
+ *
3435
+ * **Boolean predicates are terminal - they stop the chain:**
3436
+ *
3437
+ * ```typescript
3438
+ * cesdk.feature.enable('ly.img.delete'); // Default predicate: true
3439
+ * cesdk.feature.set('ly.img.delete', false); // Adds false to front
3440
+ * // Chain: [set(false), enable(true)]
3441
+ * // Evaluation: false (stops here, never reaches enable)
3442
+ * // isEnabled: false
3443
+ *
3444
+ * cesdk.feature.set('ly.img.delete', true); // Adds true to front
3445
+ * // Chain: [set(true), set(false), enable(true)]
3446
+ * // Evaluation: true (stops here, never reaches the rest)
3447
+ * // isEnabled: true
3448
+ * ```
3449
+ *
3450
+ * **Expected outcome:** The most recent `set()` call with a boolean wins because
3451
+ * boolean predicates are terminal.
3452
+ *
3453
+ * ### Use Case 4: Layering Conditions with Functions
3454
+ *
3455
+ * **Function predicates can check previous conditions:**
3456
+ *
3457
+ * ```typescript
3458
+ * // Base: Feature enabled by default
3459
+ * cesdk.feature.enable('ly.img.delete');
3460
+ *
3461
+ * // Layer 1: Add selection requirement
3462
+ * cesdk.feature.set('ly.img.delete', ({ isPreviousEnable, engine }) => {
3463
+ * const baseEnabled = isPreviousEnable(); // Checks enable(true)
3464
+ * const hasSelection = engine.block.findAllSelected().length > 0;
3465
+ * return baseEnabled && hasSelection;
3466
+ * });
3467
+ * // isEnabled: true only if enabled AND has selection
3468
+ *
3469
+ * // Layer 2: Add mode requirement
3470
+ * cesdk.feature.set('ly.img.delete', ({ isPreviousEnable, engine }) => {
3471
+ * const previousEnabled = isPreviousEnable(); // Checks Layer 1
3472
+ * const isDesignMode = engine.scene.getMode() === 'Design';
3473
+ * return previousEnabled && isDesignMode;
3474
+ * });
3475
+ * // isEnabled: true only if all conditions met (mode + selection + enabled)
3476
+ * ```
3477
+ *
3478
+ * **Expected outcome:** Each `set()` call with a function can build on previous
3479
+ * conditions by calling `isPreviousEnable()`.
3480
+ *
3481
+ * ### Use Case 5: Overriding with `set()`
3482
+ *
3483
+ * **`set()` can completely override enable/disable:**
3484
+ *
3485
+ * ```typescript
3486
+ * cesdk.feature.enable('ly.img.delete');
3487
+ * cesdk.feature.disable('ly.img.delete');
3488
+ * // isEnabled: false (disable overrides enable)
3489
+ *
3490
+ * // But set() overrides both:
3491
+ * cesdk.feature.set('ly.img.delete', true);
3492
+ * // Chain: [set(true), disable(false)]
3493
+ * // isEnabled: true (set is terminal, disable never evaluated)
3494
+ * ```
3495
+ *
3496
+ * **Expected outcome:** `set()` with a boolean always wins because it's evaluated
3497
+ * first and is terminal.
3498
+ *
3499
+ * ### Use Case 6: Glob Patterns for Bulk Operations
3500
+ *
3501
+ * **Use wildcards to affect multiple features:**
3502
+ *
3503
+ * ```typescript
3504
+ * // Enable all video features at once
3505
+ * cesdk.feature.enable('ly.img.video.*');
3506
+ *
3507
+ * // Disable all crop features
3508
+ * cesdk.feature.disable('ly.img.crop.*');
3509
+ *
3510
+ * // Set custom predicate for all navigation features
3511
+ * cesdk.feature.set('ly.img.navigation.*', ({ engine }) => {
3512
+ * return engine.scene.getMode() === 'Design';
3513
+ * });
3514
+ *
3515
+ * // Check if all video features are enabled
3516
+ * const allVideoEnabled = cesdk.feature.isEnabled('ly.img.video.*');
3517
+ * // Returns true only if ALL matching features are enabled
3518
+ * ```
3519
+ *
3520
+ * **Expected outcome:** Glob patterns match multiple features. `isEnabled()` with
3521
+ * a glob returns `true` only if **all** matching features are enabled.
3522
+ *
3523
+ * ### Use Case 7: Role-Based Access Control
3524
+ *
3525
+ * **Implement permissions using predicates:**
3526
+ *
3527
+ * ```typescript
3528
+ * const userRole = 'editor'; // Could be 'viewer', 'editor', 'admin'
3529
+ *
3530
+ * cesdk.feature.set('ly.img.delete', () => {
3531
+ * return userRole === 'editor' || userRole === 'admin';
3532
+ * });
3533
+ *
3534
+ * cesdk.feature.set('ly.img.settings', () => {
3535
+ * return userRole === 'admin';
3536
+ * });
3537
+ * ```
3538
+ *
3539
+ * **Expected outcome:** Features are enabled based on user roles, with predicates
3540
+ * evaluated on every check.
3541
+ *
3542
+ * ## Key Principles
3543
+ *
3544
+ * 1. **Use `enable()` for simple on/off** - Works with default predicates
3545
+ * 2. **Use `disable()` to turn off enabled features** - Only works if no `set()` predicates exist
3546
+ * 3. **Use `set()` for custom logic** - Overrides `enable()`/`disable()`
3547
+ * 4. **Boolean predicates are terminal** - Stop evaluation immediately
3548
+ * 5. **Function predicates can chain** - Call `isPreviousEnable()` to continue
3549
+ * 6. **Most recent `set()` wins** - Evaluated in LIFO order (most recent first)
3550
+ * 7. **Glob patterns affect multiple features** - Use `*` as wildcard
3551
+ *
3376
3552
  * @categoryDescription Feature Control
3377
3553
  * Methods for enabling and checking the status of editor features based on custom predicates.
3378
3554
  *