@yahoo/uds-create-config 2.44.0 → 3.0.0
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/README.md +129 -0
- package/dist/ai-lanes.d.ts +23 -0
- package/dist/ai-lanes.js +34 -0
- package/dist/authoring/define-component.d.ts +85 -0
- package/dist/configs/CanvasConfig.d.ts +3237 -0
- package/dist/configs/CanvasConfig.js +332 -0
- package/dist/configs/build-options.d.ts +10 -0
- package/dist/configs/build-options.js +68 -0
- package/dist/configs/platform.d.ts +15 -0
- package/dist/configs/platform.js +17 -0
- package/dist/configs/react-native-system.d.ts +3026 -0
- package/dist/configs/react-native-system.js +64 -0
- package/dist/configs/system.d.ts +2771 -0
- package/dist/configs/system.js +74 -0
- package/dist/css/properties.generated.d.ts +14 -0
- package/dist/css/properties.generated.js +6260 -0
- package/dist/css/value-type.d.ts +48 -0
- package/dist/css/value-type.js +131 -0
- package/dist/css/values.d.ts +33 -0
- package/dist/css/values.js +116 -0
- package/dist/entities/native/NativeModifier.d.ts +25 -0
- package/dist/entities/native/NativeModifier.js +41 -0
- package/dist/entities/native/NativeSettings.d.ts +44 -0
- package/dist/entities/native/NativeSettings.js +39 -0
- package/dist/entities/native/NativeStyleProperty.d.ts +355 -0
- package/dist/entities/native/NativeStyleProperty.js +28 -0
- package/dist/entities/native/NativeToken.d.ts +31 -0
- package/dist/entities/native/NativeToken.js +49 -0
- package/dist/entities/system/CanvasRole.d.ts +34 -0
- package/dist/entities/system/CanvasRole.js +45 -0
- package/dist/entities/system/Component.d.ts +1287 -0
- package/dist/entities/system/Component.js +1840 -0
- package/dist/entities/system/Composite.d.ts +12 -0
- package/dist/entities/system/Composite.js +26 -0
- package/dist/entities/system/Device.d.ts +11 -0
- package/dist/entities/system/Device.js +18 -0
- package/dist/entities/system/File.d.ts +72 -0
- package/dist/entities/system/File.js +136 -0
- package/dist/entities/system/Font.d.ts +48 -0
- package/dist/entities/system/Font.js +56 -0
- package/dist/entities/system/GlobalStyle.d.ts +26 -0
- package/dist/entities/system/GlobalStyle.js +54 -0
- package/dist/entities/system/Guidance.d.ts +85 -0
- package/dist/entities/system/Guidance.js +59 -0
- package/dist/entities/system/GuidanceStyle.d.ts +14 -0
- package/dist/entities/system/GuidanceStyle.js +8 -0
- package/dist/entities/system/Icon.d.ts +46 -0
- package/dist/entities/system/Icon.js +46 -0
- package/dist/entities/system/LinkedSystem.d.ts +504 -0
- package/dist/entities/system/LinkedSystem.js +814 -0
- package/dist/entities/system/Modifier.d.ts +92 -0
- package/dist/entities/system/Modifier.js +120 -0
- package/dist/entities/system/Motion.d.ts +28 -0
- package/dist/entities/system/Motion.js +48 -0
- package/dist/entities/system/Operation.d.ts +100 -0
- package/dist/entities/system/Operation.js +236 -0
- package/dist/entities/system/Package.d.ts +42 -0
- package/dist/entities/system/Package.js +75 -0
- package/dist/entities/system/Settings.d.ts +94 -0
- package/dist/entities/system/Settings.js +166 -0
- package/dist/entities/system/StyleProperty.d.ts +135 -0
- package/dist/entities/system/StyleProperty.js +438 -0
- package/dist/entities/system/Token.d.ts +67 -0
- package/dist/entities/system/Token.js +129 -0
- package/dist/entities/system/Tool.d.ts +134 -0
- package/dist/entities/system/Tool.js +124 -0
- package/dist/entities/system/color.d.ts +64 -0
- package/dist/entities/system/color.js +123 -0
- package/dist/entities/system/component-module.d.ts +63 -0
- package/dist/entities/system/component-module.js +258 -0
- package/dist/entities/system/copy-plan.d.ts +98 -0
- package/dist/entities/system/copy-plan.js +451 -0
- package/dist/entities/system/defineComponent.d.ts +428 -0
- package/dist/entities/system/defineComponent.js +337 -0
- package/dist/entities/system/element.d.ts +101 -0
- package/dist/entities/system/element.js +171 -0
- package/dist/entities/system/icon-library.d.ts +64 -0
- package/dist/entities/system/icon-library.js +112 -0
- package/dist/entities/system/icon-metadata.d.ts +72 -0
- package/dist/entities/system/icon-metadata.js +111 -0
- package/dist/entities/system/link-declaration.d.ts +27 -0
- package/dist/entities/system/link-declaration.js +64 -0
- package/dist/entities/system/link-plan.d.ts +160 -0
- package/dist/entities/system/link-plan.js +770 -0
- package/dist/entities/system/runtime-modules.d.ts +25 -0
- package/dist/entities/system/runtime-modules.js +38 -0
- package/dist/entities/system/style-bag.d.ts +20 -0
- package/dist/entities/system/style-bag.js +246 -0
- package/dist/entities/system/token-index.d.ts +89 -0
- package/dist/entities/system/token-index.js +112 -0
- package/dist/framework/Config.d.ts +2472 -0
- package/dist/framework/Config.js +5023 -0
- package/dist/framework/Entity.d.ts +127 -0
- package/dist/framework/Entity.js +125 -0
- package/dist/framework/authoring.d.ts +24 -0
- package/dist/framework/authoring.js +7 -0
- package/dist/framework/change-hooks.d.ts +119 -0
- package/dist/framework/change-hooks.js +131 -0
- package/dist/framework/changes.d.ts +88 -0
- package/dist/framework/changes.js +246 -0
- package/dist/framework/class-names.d.ts +260 -0
- package/dist/framework/class-names.js +630 -0
- package/dist/framework/coalesce.d.ts +25 -0
- package/dist/framework/coalesce.js +60 -0
- package/dist/framework/config-op.d.ts +76 -0
- package/dist/framework/config-op.js +43 -0
- package/dist/framework/config-operation-kind.d.ts +14 -0
- package/dist/framework/config-operation-kind.js +14 -0
- package/dist/framework/config-ops.d.ts +34 -0
- package/dist/framework/config-ops.js +187 -0
- package/dist/framework/defineConfig.d.ts +196 -0
- package/dist/framework/defineConfig.js +100 -0
- package/dist/framework/defineDerivedEntity.d.ts +74 -0
- package/dist/framework/defineDerivedEntity.js +83 -0
- package/dist/framework/defineEntity.d.ts +318 -0
- package/dist/framework/defineEntity.js +183 -0
- package/dist/framework/defineSubEntity.d.ts +148 -0
- package/dist/framework/defineSubEntity.js +121 -0
- package/dist/framework/derived-mutations.d.ts +20 -0
- package/dist/framework/derived-mutations.js +38 -0
- package/dist/framework/entity-search.d.ts +29 -0
- package/dist/framework/entity-search.js +117 -0
- package/dist/framework/inline-sources.d.ts +49 -0
- package/dist/framework/inline-sources.js +388 -0
- package/dist/framework/layer-styles.d.ts +25 -0
- package/dist/framework/layer-styles.js +49 -0
- package/dist/framework/memo.d.ts +48 -0
- package/dist/framework/memo.js +84 -0
- package/dist/framework/overlay.d.ts +49 -0
- package/dist/framework/overlay.js +17 -0
- package/dist/framework/plan.d.ts +49 -0
- package/dist/framework/plan.js +73 -0
- package/dist/framework/projections.d.ts +480 -0
- package/dist/framework/projections.js +974 -0
- package/dist/framework/prop-surface.d.ts +132 -0
- package/dist/framework/prop-surface.js +278 -0
- package/dist/framework/ref-graph.d.ts +71 -0
- package/dist/framework/ref-graph.js +158 -0
- package/dist/framework/ref-integrity.d.ts +55 -0
- package/dist/framework/ref-integrity.js +171 -0
- package/dist/framework/registered.d.ts +95 -0
- package/dist/framework/registry-dir.d.ts +42 -0
- package/dist/framework/registry-dir.js +48 -0
- package/dist/framework/registry.d.ts +300 -0
- package/dist/framework/registry.js +104 -0
- package/dist/framework/rejection.d.ts +58 -0
- package/dist/framework/rejection.js +111 -0
- package/dist/framework/rename-inference.d.ts +26 -0
- package/dist/framework/rename-inference.js +50 -0
- package/dist/framework/render-spec.d.ts +296 -0
- package/dist/framework/render-spec.js +809 -0
- package/dist/framework/schema-version.d.ts +140 -0
- package/dist/framework/schema-version.js +214 -0
- package/dist/framework/schemas.d.ts +109 -0
- package/dist/framework/schemas.js +615 -0
- package/dist/framework/session.d.ts +196 -0
- package/dist/framework/session.js +367 -0
- package/dist/framework/signature.d.ts +15 -0
- package/dist/framework/signature.js +83 -0
- package/dist/framework/snapshot.d.ts +115 -0
- package/dist/framework/snapshot.js +277 -0
- package/dist/framework/source-integrity.d.ts +226 -0
- package/dist/framework/source-integrity.js +478 -0
- package/dist/framework/sources.d.ts +211 -0
- package/dist/framework/sources.js +89 -0
- package/dist/framework/utils/compiled-schema.d.ts +23 -0
- package/dist/framework/utils/compiled-schema.js +46 -0
- package/dist/framework/utils/content-key.d.ts +15 -0
- package/dist/framework/utils/content-key.js +33 -0
- package/dist/framework/utils/enumerated.d.ts +13 -0
- package/dist/framework/utils/enumerated.js +19 -0
- package/dist/framework/utils/field-path.d.ts +95 -0
- package/dist/framework/utils/field-path.js +136 -0
- package/dist/framework/utils/field-schema.d.ts +55 -0
- package/dist/framework/utils/field-schema.js +183 -0
- package/dist/framework/utils/group.d.ts +37 -0
- package/dist/framework/utils/group.js +13 -0
- package/dist/framework/utils/package-path.d.ts +37 -0
- package/dist/framework/utils/package-path.js +61 -0
- package/dist/framework/utils/refs.d.ts +194 -0
- package/dist/framework/utils/refs.js +403 -0
- package/dist/framework/validate-spec.d.ts +27 -0
- package/dist/framework/validate-spec.js +45 -0
- package/dist/framework/value-domain.d.ts +26 -0
- package/dist/framework/value-domain.js +202 -0
- package/dist/framework/views-facade.d.ts +15 -0
- package/dist/framework/views-facade.js +19 -0
- package/dist/index.d.ts +90 -42
- package/dist/index.js +86 -37
- package/dist/migrations/2.0.0/raw-css.d.ts +11 -0
- package/dist/migrations/2.0.0/raw-css.js +72 -0
- package/dist/migrations/2.0.0/v1-artifact.d.ts +1559 -0
- package/dist/migrations/2.0.0/v1-artifact.js +1018 -0
- package/dist/migrations/20260908171448_settings_as_kind.d.ts +22 -0
- package/dist/migrations/20260908171448_settings_as_kind.js +89 -0
- package/dist/migrations/20260908194245_visible_state_pointer.d.ts +19 -0
- package/dist/migrations/20260908194245_visible_state_pointer.js +115 -0
- package/dist/migrations/20260909183001_icon_knockout_variants.d.ts +18 -0
- package/dist/migrations/20260909183001_icon_knockout_variants.js +8 -0
- package/dist/migrations/20260910212453_linked_system_link_ops.d.ts +13 -0
- package/dist/migrations/20260910212453_linked_system_link_ops.js +8 -0
- package/dist/migrations/index.d.ts +2 -0
- package/dist/migrations/index.js +2 -0
- package/dist/react-native/style-keys.generated.d.ts +10 -0
- package/dist/react-native/style-keys.generated.js +167 -0
- package/dist/renderer/RendererErrorBoundary.d.ts +32 -5
- package/dist/renderer/RendererErrorBoundary.js +59 -10
- package/dist/renderer/UdsRenderer.d.ts +11 -10
- package/dist/renderer/UdsRenderer.js +1 -1
- package/dist/renderer/assetEntries.d.ts +37 -0
- package/dist/renderer/assetEntries.js +39 -0
- package/dist/renderer/assetRenderable.d.ts +14 -6
- package/dist/renderer/assetRenderable.js +8 -2
- package/dist/renderer/componentEntry.d.ts +58 -0
- package/dist/renderer/componentEntry.js +71 -0
- package/dist/renderer/icon-library.d.ts +20 -0
- package/dist/renderer/index.d.ts +7 -7
- package/dist/renderer/index.js +5 -5
- package/dist/renderer/primitives/SlotRenderer.d.ts +1 -1
- package/dist/renderer/primitives/SlotRenderer.js +1 -1
- package/dist/renderer/runtimeComponent.d.ts +33 -0
- package/dist/renderer/runtimeComponent.js +113 -0
- package/dist/renderer/spec-content.d.ts +43 -0
- package/dist/renderer/spec-content.js +95 -0
- package/dist/renderer/wrapRegistry.d.ts +22 -37
- package/dist/renderer/wrapRegistry.js +10 -20
- package/dist/renderer/wrappers/event-bridge.js +6 -5
- package/dist/renderer/wrappers/hex-normalize.js +6 -5
- package/dist/renderer/wrappers/html-aliases.d.ts +7 -2
- package/dist/renderer/wrappers/html-aliases.js +36 -19
- package/dist/renderer/wrappers/inline-styles.js +7 -6
- package/dist/spec/asset-jsx.d.ts +18 -5
- package/dist/spec/asset-jsx.js +27 -16
- package/dist/spec/collapse-text-labels.d.ts +5 -15
- package/dist/spec/collapse-text-labels.js +26 -19
- package/dist/spec/empty-node-slots.d.ts +56 -34
- package/dist/spec/empty-node-slots.js +87 -47
- package/dist/spec/index.d.ts +21 -10
- package/dist/spec/index.js +21 -10
- package/dist/spec/jsxToSpec.d.ts +14 -9
- package/dist/spec/jsxToSpec.js +20 -3
- package/dist/spec/preview-elements.d.ts +63 -0
- package/dist/spec/preview-elements.js +89 -0
- package/dist/spec/rewrite-refs.d.ts +58 -0
- package/dist/spec/rewrite-refs.js +250 -0
- package/dist/spec/specToJsx.js +18 -29
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +39 -52
- package/dist/AssetGroup.d.ts +0 -77
- package/dist/AssetGroup.js +0 -125
- package/dist/Component.d.ts +0 -333
- package/dist/Component.js +0 -1061
- package/dist/ComponentGroup.d.ts +0 -22
- package/dist/ComponentGroup.js +0 -51
- package/dist/CompositeStyle.d.ts +0 -30
- package/dist/CompositeStyle.js +0 -59
- package/dist/Config.d.ts +0 -528
- package/dist/Config.js +0 -1712
- package/dist/Mode.d.ts +0 -41
- package/dist/Mode.js +0 -81
- package/dist/Modifier.d.ts +0 -51
- package/dist/Modifier.js +0 -97
- package/dist/MotionDef.d.ts +0 -81
- package/dist/MotionDef.js +0 -212
- package/dist/Props.d.ts +0 -332
- package/dist/Props.js +0 -35
- package/dist/Provider.d.ts +0 -20
- package/dist/Provider.js +0 -14
- package/dist/StyleProp.d.ts +0 -145
- package/dist/StyleProp.js +0 -239
- package/dist/Token.d.ts +0 -76
- package/dist/Token.js +0 -133
- package/dist/TokenGroup.d.ts +0 -33
- package/dist/TokenGroup.js +0 -69
- package/dist/asset-kind.d.ts +0 -55
- package/dist/asset-kind.js +0 -29
- package/dist/asset-value.d.ts +0 -23
- package/dist/asset-value.js +0 -40
- package/dist/brands.d.ts +0 -30
- package/dist/brands.js +0 -20
- package/dist/captureCallerPath.d.ts +0 -48
- package/dist/captureCallerPath.js +0 -95
- package/dist/colorExpressions.d.ts +0 -131
- package/dist/colorExpressions.js +0 -148
- package/dist/component-referrers.d.ts +0 -30
- package/dist/component-referrers.js +0 -40
- package/dist/config-diagnostics.d.ts +0 -21
- package/dist/config-diagnostics.js +0 -12
- package/dist/defineAssetGroup.d.ts +0 -200
- package/dist/defineAssetGroup.js +0 -323
- package/dist/defineProvider.d.ts +0 -29
- package/dist/defineProvider.js +0 -60
- package/dist/element-marker.d.ts +0 -63
- package/dist/element-marker.js +0 -113
- package/dist/entity-utils.d.ts +0 -56
- package/dist/entity-utils.js +0 -105
- package/dist/extension.d.ts +0 -55
- package/dist/extension.js +0 -214
- package/dist/factories.d.ts +0 -863
- package/dist/factories.js +0 -475
- package/dist/font-face.d.ts +0 -25
- package/dist/font-face.js +0 -72
- package/dist/foreign-component-name.d.ts +0 -21
- package/dist/foreign-component-name.js +0 -42
- package/dist/interpolate.d.ts +0 -20
- package/dist/interpolate.js +0 -10
- package/dist/jsx/__fixtures__/cross-component-preview.d.ts +0 -3
- package/dist/jsx/__fixtures__/cross-component-preview.js +0 -15
- package/dist/jsx/jsx-dev-runtime.d.ts +0 -15
- package/dist/jsx/jsx-dev-runtime.js +0 -11
- package/dist/jsx/jsx-runtime.d.ts +0 -48
- package/dist/jsx/jsx-runtime.js +0 -305
- package/dist/linked-system-pins.d.ts +0 -30
- package/dist/linked-system-pins.js +0 -45
- package/dist/linkedNodePrefixes.d.ts +0 -73
- package/dist/linkedNodePrefixes.js +0 -99
- package/dist/markers.d.ts +0 -235
- package/dist/markers.js +0 -70
- package/dist/motion-constants.d.ts +0 -37
- package/dist/motion-constants.js +0 -61
- package/dist/native/NativeConfig.d.ts +0 -56
- package/dist/native/NativeConfig.js +0 -162
- package/dist/native/assets.d.ts +0 -20
- package/dist/native/assets.js +0 -17
- package/dist/native/components.d.ts +0 -139
- package/dist/native/components.js +0 -67
- package/dist/native/index.d.ts +0 -18
- package/dist/native/index.js +0 -17
- package/dist/native/modes.d.ts +0 -10
- package/dist/native/modes.js +0 -11
- package/dist/native/types.d.ts +0 -95
- package/dist/native/types.js +0 -0
- package/dist/native/validation.d.ts +0 -8
- package/dist/native/validation.js +0 -885
- package/dist/native/values.d.ts +0 -7
- package/dist/native/values.js +0 -15
- package/dist/native.d.ts +0 -12
- package/dist/native.js +0 -10
- package/dist/refs.d.ts +0 -204
- package/dist/refs.js +0 -129
- package/dist/registry-aliases.d.ts +0 -33
- package/dist/registry-aliases.js +0 -35
- package/dist/registry-dir.d.ts +0 -22
- package/dist/registry-dir.js +0 -10
- package/dist/renderer/makeRegistry.d.ts +0 -34
- package/dist/renderer/makeRegistry.js +0 -52
- package/dist/renderer/makeUdsRenderer.d.ts +0 -13
- package/dist/renderer/makeUdsRenderer.js +0 -51
- package/dist/renderer/wrappers/component-slots.d.ts +0 -41
- package/dist/renderer/wrappers/component-slots.js +0 -66
- package/dist/renderer/wrappers/slot-resolution.d.ts +0 -25
- package/dist/renderer/wrappers/slot-resolution.js +0 -68
- package/dist/renderer/wrappers/void-elements.d.ts +0 -37
- package/dist/renderer/wrappers/void-elements.js +0 -40
- package/dist/spec/layer-props.d.ts +0 -52
- package/dist/spec/layer-props.js +0 -149
- package/dist/spec/preview-controls.d.ts +0 -44
- package/dist/spec/preview-controls.js +0 -139
- package/dist/spec/slot-refs.d.ts +0 -39
- package/dist/spec/slot-refs.js +0 -56
- package/dist/token-override-rows.d.ts +0 -68
- package/dist/token-override-rows.js +0 -233
- package/dist/tokenValueType.d.ts +0 -34
- package/dist/tokenValueType.js +0 -138
- package/dist/types/css-properties.d.ts +0 -233
- package/dist/types/css-properties.js +0 -14
- package/dist/types/css-property-keywords.d.ts +0 -156
- package/dist/types/css-property-keywords.js +0 -616
- package/dist/types/css-values.d.ts +0 -63
- package/dist/types/css-values.js +0 -16
- package/dist/types.d.ts +0 -1138
- package/dist/types.js +0 -12
- package/dist/units.d.ts +0 -14
- package/dist/units.js +0 -16
- package/dist/utils/index.d.ts +0 -4
- package/dist/utils/index.js +0 -4
|
@@ -0,0 +1,770 @@
|
|
|
1
|
+
import { rejectData } from "../../framework/rejection.js";
|
|
2
|
+
import { collectRefs, isMintedRow, ref, sourceOf, splitRef } from "../../framework/utils/refs.js";
|
|
3
|
+
import { blockedBy } from "../../framework/plan.js";
|
|
4
|
+
import { PIN_KIND, covers, declarationOf, narrowDeclaration } from "./link-declaration.js";
|
|
5
|
+
import { planCopy, sourceEntries } from "./copy-plan.js";
|
|
6
|
+
//#region src/entities/system/link-plan.ts
|
|
7
|
+
/** The kinds `data` names, with what to take of each. An accessor this config has no kind for is a typo, refused by name. */
|
|
8
|
+
function wantedKinds({ config, slug, data, verb }) {
|
|
9
|
+
const wanted = [];
|
|
10
|
+
if (data === "*") for (const kind of config.borrowableKinds(slug)) wanted.push({
|
|
11
|
+
kind,
|
|
12
|
+
accessor: config.accessorOf(kind) ?? kind,
|
|
13
|
+
paths: "*"
|
|
14
|
+
});
|
|
15
|
+
else {
|
|
16
|
+
const accessors = config.accessors();
|
|
17
|
+
for (const [accessor, paths] of Object.entries(data)) {
|
|
18
|
+
const cls = accessors[accessor];
|
|
19
|
+
if (!cls) rejectData(`Cannot ${verb} through "${slug}" — this system has no "${accessor}".`, ["data", accessor]);
|
|
20
|
+
wanted.push({
|
|
21
|
+
kind: cls.kind,
|
|
22
|
+
accessor,
|
|
23
|
+
paths
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
if (wanted.length === 0) rejectData(`Cannot ${verb} through "${slug}" — name what to take in \`data\`.`);
|
|
28
|
+
return wanted;
|
|
29
|
+
}
|
|
30
|
+
/** Whether the row here and the source's row at the path trace to one origin, so the source is a second route to something already held. */
|
|
31
|
+
function sharedWithOrigin({ config, source, slug, kind, path }) {
|
|
32
|
+
const held = config.resolve(kind, path);
|
|
33
|
+
if (!held || held.copiedThrough === slug) return void 0;
|
|
34
|
+
const theirs = source.originOf({
|
|
35
|
+
kind,
|
|
36
|
+
path
|
|
37
|
+
});
|
|
38
|
+
const mine = theirs && config.originOf({
|
|
39
|
+
kind,
|
|
40
|
+
path
|
|
41
|
+
});
|
|
42
|
+
if (!theirs || !mine || theirs.key !== mine.key) return void 0;
|
|
43
|
+
return theirs.pin.displayName ?? theirs.key;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Link paths of a source: the declaration that mints them, then the edits that let them show through
|
|
47
|
+
* where this config already holds something.
|
|
48
|
+
*
|
|
49
|
+
* The declaration goes first. A row of this config's own that other rows point at can only be deleted
|
|
50
|
+
* once the declaration covers the path, since the config refuses a delete that leaves a referrer
|
|
51
|
+
* dangling. A row held through another pin is not deleted — that pin's declaration would mint it
|
|
52
|
+
* again, and declaring one path on two pins is a collision nothing derives — so it becomes an
|
|
53
|
+
* extension through this pin: a row of this config's own that shadows the other pin's and follows this
|
|
54
|
+
* source. A member already here from the source's own origin is left alone and kept out of the
|
|
55
|
+
* declaration, so a folder that holds one is declared by its other members.
|
|
56
|
+
*/
|
|
57
|
+
function planLink({ config, input }) {
|
|
58
|
+
const { path: slug } = input;
|
|
59
|
+
const source = config.sourceFor(slug);
|
|
60
|
+
if (!source) rejectData(`Cannot link through "${slug}" — nothing has resolved that link.`);
|
|
61
|
+
const current = declarationOf(config, slug);
|
|
62
|
+
const wanted = wantedKinds({
|
|
63
|
+
config,
|
|
64
|
+
slug,
|
|
65
|
+
data: input.data,
|
|
66
|
+
verb: "link"
|
|
67
|
+
});
|
|
68
|
+
const addresses = [];
|
|
69
|
+
const extended = [];
|
|
70
|
+
const shared = [];
|
|
71
|
+
const shadows = [];
|
|
72
|
+
/** Per accessor, what the declaration gains: the kind whole, or paths. */
|
|
73
|
+
const gains = /* @__PURE__ */ new Map();
|
|
74
|
+
let sharedAnywhere = false;
|
|
75
|
+
const shadow = (kind, path) => {
|
|
76
|
+
const held = config.resolve(kind, path);
|
|
77
|
+
if (!held || held.borrowedFrom === slug) return true;
|
|
78
|
+
if (sharedWithOrigin({
|
|
79
|
+
config,
|
|
80
|
+
source,
|
|
81
|
+
slug,
|
|
82
|
+
kind,
|
|
83
|
+
path
|
|
84
|
+
}) !== void 0) {
|
|
85
|
+
shared.push({
|
|
86
|
+
kind,
|
|
87
|
+
path
|
|
88
|
+
});
|
|
89
|
+
sharedAnywhere = true;
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
if (held.borrowedFrom === void 0) {
|
|
93
|
+
addresses.push({
|
|
94
|
+
kind,
|
|
95
|
+
path
|
|
96
|
+
});
|
|
97
|
+
shadows.push({
|
|
98
|
+
kind,
|
|
99
|
+
operation: "delete",
|
|
100
|
+
path
|
|
101
|
+
});
|
|
102
|
+
return true;
|
|
103
|
+
}
|
|
104
|
+
const stored = config.storedBody(kind, path);
|
|
105
|
+
const minted = stored !== void 0 && isMintedRow(stored);
|
|
106
|
+
extended.push({
|
|
107
|
+
kind,
|
|
108
|
+
path
|
|
109
|
+
});
|
|
110
|
+
shadows.push({
|
|
111
|
+
kind,
|
|
112
|
+
operation: minted ? "create" : "replace",
|
|
113
|
+
path,
|
|
114
|
+
data: {
|
|
115
|
+
...ref(kind, path, slug),
|
|
116
|
+
extend: {}
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
return true;
|
|
120
|
+
};
|
|
121
|
+
for (const { kind, accessor, paths } of wanted) {
|
|
122
|
+
const named = paths === "*" ? ["*"] : paths;
|
|
123
|
+
const gained = [];
|
|
124
|
+
let whole = paths === "*";
|
|
125
|
+
for (const path of named) {
|
|
126
|
+
const entries = sourceEntries({
|
|
127
|
+
source,
|
|
128
|
+
kind,
|
|
129
|
+
path
|
|
130
|
+
});
|
|
131
|
+
if (entries.length === 0) {
|
|
132
|
+
if (path === "*") continue;
|
|
133
|
+
rejectData(`Cannot link "${path}" through "${slug}" — the source has no ${kind} there.`, ["data", accessor]);
|
|
134
|
+
}
|
|
135
|
+
const taken = entries.filter((entry) => shadow(kind, entry.from));
|
|
136
|
+
if (taken.length === entries.length) {
|
|
137
|
+
if (path !== "*") gained.push(path);
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
whole = false;
|
|
141
|
+
gained.push(...taken.map((entry) => entry.from));
|
|
142
|
+
}
|
|
143
|
+
if (whole) gains.set(accessor, "*");
|
|
144
|
+
else if (gained.length > 0) gains.set(accessor, gained);
|
|
145
|
+
}
|
|
146
|
+
const declares = [];
|
|
147
|
+
let declared = current;
|
|
148
|
+
if (current !== "*") if (input.data === "*" && !sharedAnywhere) {
|
|
149
|
+
declared = "*";
|
|
150
|
+
declares.push({
|
|
151
|
+
kind: PIN_KIND,
|
|
152
|
+
operation: "update",
|
|
153
|
+
path: slug,
|
|
154
|
+
data: { link: "*" }
|
|
155
|
+
});
|
|
156
|
+
} else {
|
|
157
|
+
const next = { ...current ?? {} };
|
|
158
|
+
for (const [accessor, gain] of gains) {
|
|
159
|
+
const before = next[accessor];
|
|
160
|
+
if (before === "*") continue;
|
|
161
|
+
if (gain === "*") {
|
|
162
|
+
next[accessor] = "*";
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
const added = gain.filter((path) => !covers({
|
|
166
|
+
declared: current,
|
|
167
|
+
accessor,
|
|
168
|
+
path
|
|
169
|
+
}));
|
|
170
|
+
if (added.length === 0) continue;
|
|
171
|
+
next[accessor] = [...before ?? [], ...new Set(added)];
|
|
172
|
+
}
|
|
173
|
+
for (const [accessor, value] of Object.entries(next)) {
|
|
174
|
+
if (current !== void 0 && current[accessor] === value) continue;
|
|
175
|
+
declares.push({
|
|
176
|
+
kind: PIN_KIND,
|
|
177
|
+
operation: "update",
|
|
178
|
+
path: slug,
|
|
179
|
+
data: { [`link.${accessor}`]: value }
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
declared = Object.keys(next).length === 0 ? current : next;
|
|
183
|
+
}
|
|
184
|
+
const patches = [...declares, ...shadows];
|
|
185
|
+
return {
|
|
186
|
+
declared,
|
|
187
|
+
arriving: arrivals({
|
|
188
|
+
config,
|
|
189
|
+
slug,
|
|
190
|
+
patches,
|
|
191
|
+
named: input.data
|
|
192
|
+
}),
|
|
193
|
+
replaces: addresses.length,
|
|
194
|
+
addresses,
|
|
195
|
+
extended,
|
|
196
|
+
shared,
|
|
197
|
+
patches
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* The rows a link mints, read by running its patches on a scratch config and deriving: what is held
|
|
202
|
+
* through the pin afterwards and was not before. Nothing when the op would refuse; the op says why.
|
|
203
|
+
*/
|
|
204
|
+
function arrivals({ config, slug, patches, named }) {
|
|
205
|
+
if (patches.length === 0) return [];
|
|
206
|
+
const through = (at) => {
|
|
207
|
+
const held = /* @__PURE__ */ new Set();
|
|
208
|
+
for (const kind of at.borrowableKinds(slug)) for (const item of at.list(kind)) if (item.borrowedFrom === slug) held.add(`${kind}:${item.path}`);
|
|
209
|
+
return held;
|
|
210
|
+
};
|
|
211
|
+
let after;
|
|
212
|
+
try {
|
|
213
|
+
after = config.applyAll(patches).withDerivedRows();
|
|
214
|
+
} catch {
|
|
215
|
+
return [];
|
|
216
|
+
}
|
|
217
|
+
const before = through(config);
|
|
218
|
+
const arriving = [];
|
|
219
|
+
for (const key of through(after)) {
|
|
220
|
+
if (before.has(key)) continue;
|
|
221
|
+
const { kind, path } = splitRef(key);
|
|
222
|
+
const accessor = config.accessorOf(kind) ?? kind;
|
|
223
|
+
arriving.push({
|
|
224
|
+
kind,
|
|
225
|
+
path,
|
|
226
|
+
named: covers({
|
|
227
|
+
declared: named,
|
|
228
|
+
accessor,
|
|
229
|
+
path
|
|
230
|
+
})
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
return arriving;
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Stop drawing paths of a source. The declaration narrows, or clears, and the rows it minted retire
|
|
237
|
+
* with it inside the apply; nothing authored here moves. Named paths take the linked rows that point
|
|
238
|
+
* at them along (`cascade`), since left linked those would bring them back. A row of this config's own
|
|
239
|
+
* pointing at a minted row would be stranded, and the config refuses that, which `blocked` reports.
|
|
240
|
+
*/
|
|
241
|
+
function planUnlink({ config, input }) {
|
|
242
|
+
const { path: slug } = input;
|
|
243
|
+
const current = declarationOf(config, slug);
|
|
244
|
+
if (current === void 0) return {
|
|
245
|
+
declared: void 0,
|
|
246
|
+
removed: [],
|
|
247
|
+
cascade: [],
|
|
248
|
+
patches: []
|
|
249
|
+
};
|
|
250
|
+
let declared;
|
|
251
|
+
const patches = [];
|
|
252
|
+
const cascade = [];
|
|
253
|
+
if (input.data === void 0 || input.data === "*") {
|
|
254
|
+
declared = void 0;
|
|
255
|
+
patches.push({
|
|
256
|
+
kind: PIN_KIND,
|
|
257
|
+
operation: "update",
|
|
258
|
+
path: slug,
|
|
259
|
+
data: { link: null }
|
|
260
|
+
});
|
|
261
|
+
} else {
|
|
262
|
+
const removal = /* @__PURE__ */ new Map();
|
|
263
|
+
for (const { accessor, paths } of wantedKinds({
|
|
264
|
+
config,
|
|
265
|
+
slug,
|
|
266
|
+
data: input.data,
|
|
267
|
+
verb: "unlink"
|
|
268
|
+
})) removal.set(accessor, paths === "*" ? "*" : [...paths]);
|
|
269
|
+
for (const row of linkedDependents({
|
|
270
|
+
config,
|
|
271
|
+
slug,
|
|
272
|
+
data: input.data
|
|
273
|
+
})) {
|
|
274
|
+
const accessor = config.accessorOf(row.kind) ?? row.kind;
|
|
275
|
+
const listed = removal.get(accessor);
|
|
276
|
+
if (listed === "*") continue;
|
|
277
|
+
if (listed?.some((path) => path === row.path || row.path.startsWith(`${path}/`))) continue;
|
|
278
|
+
cascade.push(row);
|
|
279
|
+
removal.set(accessor, [...listed ?? [], row.path]);
|
|
280
|
+
}
|
|
281
|
+
declared = narrowDeclaration({
|
|
282
|
+
config,
|
|
283
|
+
slug,
|
|
284
|
+
current,
|
|
285
|
+
removal,
|
|
286
|
+
verb: "unlink"
|
|
287
|
+
});
|
|
288
|
+
patches.push({
|
|
289
|
+
kind: PIN_KIND,
|
|
290
|
+
operation: "update",
|
|
291
|
+
path: slug,
|
|
292
|
+
data: { link: declared === void 0 ? null : declared }
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
let blocked = blockedBy(() => config.applyAll(patches));
|
|
296
|
+
const removed = [];
|
|
297
|
+
if (blocked === void 0) {
|
|
298
|
+
const after = config.applyAll(patches);
|
|
299
|
+
for (const kind of config.borrowableKinds(slug)) for (const item of config.list(kind)) {
|
|
300
|
+
if (item.borrowedFrom !== slug) continue;
|
|
301
|
+
if (after.resolve(kind, item.path)?.borrowedFrom === slug) continue;
|
|
302
|
+
removed.push({
|
|
303
|
+
kind,
|
|
304
|
+
path: item.path
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
if (input.data !== void 0 && removed.length === 0) blocked = stillReached({ slug });
|
|
308
|
+
}
|
|
309
|
+
return {
|
|
310
|
+
declared,
|
|
311
|
+
removed,
|
|
312
|
+
cascade,
|
|
313
|
+
...blocked === void 0 ? {} : { blocked },
|
|
314
|
+
patches
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* The linked rows that point at what `data` names, followed to a fixpoint: a row pointing at one of
|
|
319
|
+
* those, and so on. Read off both ref graphs, since a linked row's refs are the source's spelling and
|
|
320
|
+
* this config's index holds them qualified.
|
|
321
|
+
*/
|
|
322
|
+
function linkedDependents({ config, slug, data }) {
|
|
323
|
+
const source = config.sourceFor(slug);
|
|
324
|
+
const named = /* @__PURE__ */ new Set();
|
|
325
|
+
for (const { kind, paths } of wantedKinds({
|
|
326
|
+
config,
|
|
327
|
+
slug,
|
|
328
|
+
data,
|
|
329
|
+
verb: "unlink"
|
|
330
|
+
})) {
|
|
331
|
+
const list = paths === "*" ? ["*"] : paths;
|
|
332
|
+
for (const path of list) {
|
|
333
|
+
if (path !== "*") named.add(`${kind}:${path}`);
|
|
334
|
+
if (!source) continue;
|
|
335
|
+
for (const entry of sourceEntries({
|
|
336
|
+
source,
|
|
337
|
+
kind,
|
|
338
|
+
path
|
|
339
|
+
})) named.add(`${kind}:${entry.from}`);
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
const found = /* @__PURE__ */ new Map();
|
|
343
|
+
const linkedHere = (referrer) => {
|
|
344
|
+
const parts = splitRef(referrer);
|
|
345
|
+
if (parts.member !== void 0 || parts.source !== void 0) return;
|
|
346
|
+
const key = `${parts.kind}:${parts.path}`;
|
|
347
|
+
if (named.has(key) || found.has(key)) return;
|
|
348
|
+
if (config.resolve(parts.kind, parts.path)?.borrowedFrom !== slug) return;
|
|
349
|
+
return {
|
|
350
|
+
kind: parts.kind,
|
|
351
|
+
path: parts.path
|
|
352
|
+
};
|
|
353
|
+
};
|
|
354
|
+
const queue = [...named];
|
|
355
|
+
while (queue.length > 0) {
|
|
356
|
+
const target = queue.shift();
|
|
357
|
+
const referrers = [...config.refs.dependents(target), ...source ? source.refs.dependents(target) : []];
|
|
358
|
+
for (const referrer of referrers) {
|
|
359
|
+
const row = linkedHere(referrer);
|
|
360
|
+
if (!row) continue;
|
|
361
|
+
found.set(`${row.kind}:${row.path}`, row);
|
|
362
|
+
queue.push(`${row.kind}:${row.path}`);
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
return [...found.values()];
|
|
366
|
+
}
|
|
367
|
+
/** Why an unlink of named paths would change nothing, when even its cascade left them minted. */
|
|
368
|
+
function stillReached({ slug }) {
|
|
369
|
+
return `Nothing would go: what "${slug}" declares still reaches everything named. Keep the values as yours instead.`;
|
|
370
|
+
}
|
|
371
|
+
/** What a copy names, accumulated as `copy` takes it. */
|
|
372
|
+
var CopyRequest = class {
|
|
373
|
+
#whole = false;
|
|
374
|
+
#byAccessor = /* @__PURE__ */ new Map();
|
|
375
|
+
constructor(config) {
|
|
376
|
+
this.config = config;
|
|
377
|
+
}
|
|
378
|
+
everything() {
|
|
379
|
+
this.#whole = true;
|
|
380
|
+
}
|
|
381
|
+
kind(accessor) {
|
|
382
|
+
this.#byAccessor.set(accessor, "*");
|
|
383
|
+
}
|
|
384
|
+
path(kind, path) {
|
|
385
|
+
const accessor = this.config.accessorOf(kind) ?? kind;
|
|
386
|
+
const current = this.#byAccessor.get(accessor);
|
|
387
|
+
if (current === "*") return;
|
|
388
|
+
if (current) current.add(path);
|
|
389
|
+
else this.#byAccessor.set(accessor, new Set([path]));
|
|
390
|
+
}
|
|
391
|
+
get empty() {
|
|
392
|
+
return !this.#whole && this.#byAccessor.size === 0;
|
|
393
|
+
}
|
|
394
|
+
get data() {
|
|
395
|
+
if (this.#whole) return "*";
|
|
396
|
+
return Object.fromEntries([...this.#byAccessor].map(([accessor, paths]) => [accessor, paths === "*" ? "*" : [...paths]]));
|
|
397
|
+
}
|
|
398
|
+
};
|
|
399
|
+
/** The refs a row of this config's own holds through the pin, as the row spells them. */
|
|
400
|
+
function drawnThroughPin({ config, slug, kind, path }) {
|
|
401
|
+
return [...new Set(collectRefs(config.storedBody(kind, path)).filter((target) => sourceOf(target) === slug && splitRef(target).member === void 0))];
|
|
402
|
+
}
|
|
403
|
+
/**
|
|
404
|
+
* Break a link: everything drawn through the pin becomes this config's own, or is dropped, and the
|
|
405
|
+
* pin goes.
|
|
406
|
+
*
|
|
407
|
+
* With `keep`, every entity drawn through the pin is copied in — the value the source holds today,
|
|
408
|
+
* written as a row of this config's own — and a row of yours that pointed through the pin has its
|
|
409
|
+
* targets copied too, with the copy pointing it at the copies. The declaration is then cleared and
|
|
410
|
+
* the pin deleted; nothing refers to it by then. Without `keep`, the declaration is cleared and the
|
|
411
|
+
* pin deleted, and a row of yours still pointing through it is what refuses the break.
|
|
412
|
+
*
|
|
413
|
+
* With `data`, the pin stays and the account is of those paths alone: with `keep`, detaching them
|
|
414
|
+
* through `copy` — the rows the copy lands, the rows of yours it rebinds, and the rows still linked
|
|
415
|
+
* that reference what moves; without it, an `unlink` of them — the rows that go, and the refusal a
|
|
416
|
+
* row of yours pointing at one would raise.
|
|
417
|
+
*/
|
|
418
|
+
function planBreak({ config, input }) {
|
|
419
|
+
const { path: slug } = input;
|
|
420
|
+
const declared = declarationOf(config, slug);
|
|
421
|
+
const scoped = input.data !== void 0;
|
|
422
|
+
const keep = input.keep ?? true;
|
|
423
|
+
const rows = [];
|
|
424
|
+
const seen = /* @__PURE__ */ new Set();
|
|
425
|
+
const rowOf = (row) => {
|
|
426
|
+
const key = `${row.kind}:${row.path}`;
|
|
427
|
+
if (seen.has(key)) return;
|
|
428
|
+
seen.add(key);
|
|
429
|
+
rows.push(row);
|
|
430
|
+
};
|
|
431
|
+
if (scoped && !keep) {
|
|
432
|
+
const plan = planUnlink({
|
|
433
|
+
config,
|
|
434
|
+
input: {
|
|
435
|
+
path: slug,
|
|
436
|
+
data: input.data
|
|
437
|
+
}
|
|
438
|
+
});
|
|
439
|
+
const cascaded = new Set(plan.cascade.map((row) => `${row.kind}:${row.path}`));
|
|
440
|
+
for (const { kind, path } of plan.removed) rowOf({
|
|
441
|
+
kind,
|
|
442
|
+
path,
|
|
443
|
+
folder: false,
|
|
444
|
+
refs: [ref(kind, path, slug).__ref],
|
|
445
|
+
outcome: "dropped",
|
|
446
|
+
reach: cascaded.has(`${kind}:${path}`) ? "taken" : "direct"
|
|
447
|
+
});
|
|
448
|
+
return {
|
|
449
|
+
rows,
|
|
450
|
+
...plan.blocked === void 0 ? {} : { blocked: plan.blocked },
|
|
451
|
+
patches: plan.patches
|
|
452
|
+
};
|
|
453
|
+
}
|
|
454
|
+
if (!scoped && !keep) {
|
|
455
|
+
for (const kind of config.borrowableKinds(slug)) for (const item of config.list(kind)) {
|
|
456
|
+
if (item.borrowedFrom !== slug) continue;
|
|
457
|
+
rowOf({
|
|
458
|
+
kind,
|
|
459
|
+
path: item.path,
|
|
460
|
+
folder: false,
|
|
461
|
+
refs: [ref(kind, item.path, slug).__ref],
|
|
462
|
+
outcome: "dropped",
|
|
463
|
+
reach: "direct"
|
|
464
|
+
});
|
|
465
|
+
}
|
|
466
|
+
const patches = [...declared === void 0 ? [] : [{
|
|
467
|
+
kind: PIN_KIND,
|
|
468
|
+
operation: "update",
|
|
469
|
+
path: slug,
|
|
470
|
+
data: { link: null }
|
|
471
|
+
}], {
|
|
472
|
+
kind: PIN_KIND,
|
|
473
|
+
operation: "delete",
|
|
474
|
+
path: slug
|
|
475
|
+
}];
|
|
476
|
+
const blocked = blockedBy(() => config.applyAll(patches));
|
|
477
|
+
return {
|
|
478
|
+
rows,
|
|
479
|
+
...blocked === void 0 ? {} : { blocked },
|
|
480
|
+
patches
|
|
481
|
+
};
|
|
482
|
+
}
|
|
483
|
+
const copying = new CopyRequest(config);
|
|
484
|
+
/** Rows of this config's own that point through the pin, and what each drew. */
|
|
485
|
+
const pointing = /* @__PURE__ */ new Map();
|
|
486
|
+
/** Folders drawn through the pin by a pointer of this config's own, released once their members are copied. */
|
|
487
|
+
const pointedFolders = [];
|
|
488
|
+
const reach = ({ kind, path, reach }) => {
|
|
489
|
+
const held = config.resolve(kind, path);
|
|
490
|
+
if (held?.borrowedFrom === slug) {
|
|
491
|
+
copying.path(kind, path);
|
|
492
|
+
rowOf({
|
|
493
|
+
kind,
|
|
494
|
+
path,
|
|
495
|
+
folder: false,
|
|
496
|
+
refs: [ref(kind, path, slug).__ref],
|
|
497
|
+
outcome: "copied",
|
|
498
|
+
reach
|
|
499
|
+
});
|
|
500
|
+
return;
|
|
501
|
+
}
|
|
502
|
+
if (!held) {
|
|
503
|
+
if (config.groupBorrowedFrom({
|
|
504
|
+
kind,
|
|
505
|
+
groupPath: path
|
|
506
|
+
}) === slug) {
|
|
507
|
+
copying.path(kind, path);
|
|
508
|
+
const meta = config.groupMeta(kind, path);
|
|
509
|
+
if (meta && !isMintedRow(meta)) pointedFolders.push({
|
|
510
|
+
kind,
|
|
511
|
+
path
|
|
512
|
+
});
|
|
513
|
+
rowOf({
|
|
514
|
+
kind,
|
|
515
|
+
path,
|
|
516
|
+
folder: true,
|
|
517
|
+
refs: [ref(kind, path, slug).__ref],
|
|
518
|
+
outcome: "copied",
|
|
519
|
+
reach
|
|
520
|
+
});
|
|
521
|
+
}
|
|
522
|
+
return;
|
|
523
|
+
}
|
|
524
|
+
const refs = drawnThroughPin({
|
|
525
|
+
config,
|
|
526
|
+
slug,
|
|
527
|
+
kind,
|
|
528
|
+
path
|
|
529
|
+
});
|
|
530
|
+
if (refs.length === 0) return;
|
|
531
|
+
for (const target of refs) {
|
|
532
|
+
const parts = splitRef(target);
|
|
533
|
+
copying.path(parts.kind, parts.path);
|
|
534
|
+
}
|
|
535
|
+
pointing.set(`${kind}:${path}`, {
|
|
536
|
+
refs,
|
|
537
|
+
reach
|
|
538
|
+
});
|
|
539
|
+
};
|
|
540
|
+
if (scoped) for (const { kind, accessor, paths } of wantedKinds({
|
|
541
|
+
config,
|
|
542
|
+
slug,
|
|
543
|
+
data: input.data,
|
|
544
|
+
verb: "break"
|
|
545
|
+
})) {
|
|
546
|
+
if (paths === "*") {
|
|
547
|
+
copying.kind(accessor);
|
|
548
|
+
continue;
|
|
549
|
+
}
|
|
550
|
+
for (const path of paths) reach({
|
|
551
|
+
kind,
|
|
552
|
+
path,
|
|
553
|
+
reach: "direct"
|
|
554
|
+
});
|
|
555
|
+
}
|
|
556
|
+
else {
|
|
557
|
+
if (declared === "*") copying.everything();
|
|
558
|
+
else if (declared) {
|
|
559
|
+
for (const [accessor, paths] of Object.entries(declared)) if (paths === "*") copying.kind(accessor);
|
|
560
|
+
}
|
|
561
|
+
for (const dependent of config.dependentsOf(PIN_KIND, slug)) {
|
|
562
|
+
const { kind, path } = splitRef(dependent);
|
|
563
|
+
const held = config.resolve(kind, path);
|
|
564
|
+
reach({
|
|
565
|
+
kind,
|
|
566
|
+
path,
|
|
567
|
+
reach: held?.borrowedFrom === slug || !held ? "direct" : "indirect"
|
|
568
|
+
});
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
const patches = [];
|
|
572
|
+
const released = /* @__PURE__ */ new Set();
|
|
573
|
+
let copyBlocked;
|
|
574
|
+
if (!copying.empty) copyBlocked = blockedBy(() => {
|
|
575
|
+
const plan = planCopy({
|
|
576
|
+
config,
|
|
577
|
+
input: {
|
|
578
|
+
path: slug,
|
|
579
|
+
data: copying.data
|
|
580
|
+
}
|
|
581
|
+
});
|
|
582
|
+
for (const row of plan.rows) rowOf({
|
|
583
|
+
kind: row.kind,
|
|
584
|
+
path: row.path,
|
|
585
|
+
folder: false,
|
|
586
|
+
refs: [ref(row.kind, row.path, slug).__ref],
|
|
587
|
+
outcome: "copied",
|
|
588
|
+
reach: "taken"
|
|
589
|
+
});
|
|
590
|
+
for (const { kind, path } of plan.rebound) {
|
|
591
|
+
const drew = pointing.get(`${kind}:${path}`);
|
|
592
|
+
rowOf({
|
|
593
|
+
kind,
|
|
594
|
+
path,
|
|
595
|
+
folder: false,
|
|
596
|
+
refs: drew?.refs ?? drawnThroughPin({
|
|
597
|
+
config,
|
|
598
|
+
slug,
|
|
599
|
+
kind,
|
|
600
|
+
path
|
|
601
|
+
}),
|
|
602
|
+
outcome: "rebound",
|
|
603
|
+
reach: drew?.reach ?? "indirect"
|
|
604
|
+
});
|
|
605
|
+
}
|
|
606
|
+
for (const folder of plan.folders) released.add(`${folder.kind}:${folder.path}`);
|
|
607
|
+
patches.push(...plan.patches.filter((patch) => scoped || !(patch.kind === "linked-system" && patch.operation === "update")));
|
|
608
|
+
});
|
|
609
|
+
if (copyBlocked !== void 0) return {
|
|
610
|
+
rows,
|
|
611
|
+
blocked: copyBlocked,
|
|
612
|
+
patches: []
|
|
613
|
+
};
|
|
614
|
+
reachReferrers({
|
|
615
|
+
config,
|
|
616
|
+
slug,
|
|
617
|
+
rows,
|
|
618
|
+
rowOf
|
|
619
|
+
});
|
|
620
|
+
if (scoped) return {
|
|
621
|
+
rows,
|
|
622
|
+
patches
|
|
623
|
+
};
|
|
624
|
+
for (const folder of pointedFolders) {
|
|
625
|
+
if (released.has(`${folder.kind}:${folder.path}`)) continue;
|
|
626
|
+
patches.push({
|
|
627
|
+
kind: folder.kind,
|
|
628
|
+
operation: "group-update",
|
|
629
|
+
path: folder.path,
|
|
630
|
+
data: { ref: null }
|
|
631
|
+
});
|
|
632
|
+
}
|
|
633
|
+
if (declared !== void 0) patches.push({
|
|
634
|
+
kind: PIN_KIND,
|
|
635
|
+
operation: "update",
|
|
636
|
+
path: slug,
|
|
637
|
+
data: { link: null }
|
|
638
|
+
});
|
|
639
|
+
patches.push({
|
|
640
|
+
kind: PIN_KIND,
|
|
641
|
+
operation: "delete",
|
|
642
|
+
path: slug
|
|
643
|
+
});
|
|
644
|
+
const blocked = blockedBy(() => config.applyAll(patches));
|
|
645
|
+
return {
|
|
646
|
+
rows,
|
|
647
|
+
...blocked === void 0 ? {} : { blocked },
|
|
648
|
+
patches
|
|
649
|
+
};
|
|
650
|
+
}
|
|
651
|
+
/**
|
|
652
|
+
* The rows that reference what a break copies without pointing through the pin themselves. Yours are
|
|
653
|
+
* rebound onto the copies; the source's own, still linked, keep following the source.
|
|
654
|
+
*/
|
|
655
|
+
function reachReferrers({ config, slug, rows, rowOf }) {
|
|
656
|
+
const copied = rows.filter((row) => row.outcome === "copied");
|
|
657
|
+
const copiedKeys = new Set(copied.map((row) => `${row.kind}:${row.path}`));
|
|
658
|
+
const source = config.sourceFor(slug);
|
|
659
|
+
const referrerOf = (referrer) => {
|
|
660
|
+
const parts = splitRef(referrer);
|
|
661
|
+
if (parts.member !== void 0 || parts.source !== void 0) return;
|
|
662
|
+
if (copiedKeys.has(`${parts.kind}:${parts.path}`)) return;
|
|
663
|
+
return parts;
|
|
664
|
+
};
|
|
665
|
+
const yours = /* @__PURE__ */ new Map();
|
|
666
|
+
const theirs = /* @__PURE__ */ new Map();
|
|
667
|
+
for (const { kind, path } of copied) {
|
|
668
|
+
const target = `${kind}:${path}`;
|
|
669
|
+
for (const referrer of config.refs.dependents(target)) {
|
|
670
|
+
const parts = referrerOf(referrer);
|
|
671
|
+
if (!parts) continue;
|
|
672
|
+
const body = config.storedBody(parts.kind, parts.path);
|
|
673
|
+
if (!body || isMintedRow(body)) continue;
|
|
674
|
+
const held = yours.get(`${parts.kind}:${parts.path}`) ?? /* @__PURE__ */ new Set();
|
|
675
|
+
held.add(target);
|
|
676
|
+
yours.set(`${parts.kind}:${parts.path}`, held);
|
|
677
|
+
}
|
|
678
|
+
if (!source) continue;
|
|
679
|
+
for (const referrer of source.refs.dependents(target)) {
|
|
680
|
+
const parts = referrerOf(referrer);
|
|
681
|
+
if (!parts) continue;
|
|
682
|
+
if (config.resolve(parts.kind, parts.path)?.borrowedFrom !== slug) continue;
|
|
683
|
+
const held = theirs.get(`${parts.kind}:${parts.path}`) ?? /* @__PURE__ */ new Set();
|
|
684
|
+
held.add(ref(kind, path, slug).__ref);
|
|
685
|
+
theirs.set(`${parts.kind}:${parts.path}`, held);
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
for (const [key, refs] of yours) {
|
|
689
|
+
const { kind, path } = splitRef(key);
|
|
690
|
+
rowOf({
|
|
691
|
+
kind,
|
|
692
|
+
path,
|
|
693
|
+
folder: false,
|
|
694
|
+
refs: [...refs],
|
|
695
|
+
outcome: "rebound",
|
|
696
|
+
reach: "indirect"
|
|
697
|
+
});
|
|
698
|
+
}
|
|
699
|
+
for (const [key, refs] of theirs) {
|
|
700
|
+
const { kind, path } = splitRef(key);
|
|
701
|
+
rowOf({
|
|
702
|
+
kind,
|
|
703
|
+
path,
|
|
704
|
+
folder: false,
|
|
705
|
+
refs: [...refs],
|
|
706
|
+
outcome: "follows",
|
|
707
|
+
reach: "linked"
|
|
708
|
+
});
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
const leafItems = (node) => node.type === "item" && node.children.length === 0 ? [node] : [...node.type === "item" ? [node] : [], ...node.children.flatMap(leafItems)];
|
|
712
|
+
/**
|
|
713
|
+
* The source's top-level tree, one row per node, read against what this config holds at each path.
|
|
714
|
+
*
|
|
715
|
+
* Reads the live source, since the closure only carries what this config already reached and a source
|
|
716
|
+
* with nothing linked would list nothing. Kinds are `borrowableKinds`, the intersection of what the
|
|
717
|
+
* source has and this config can hold. Nothing when no source is attached.
|
|
718
|
+
*/
|
|
719
|
+
function sourceRowStates({ config, slug }) {
|
|
720
|
+
const source = config.liveSourceFor(slug);
|
|
721
|
+
if (!source) return [];
|
|
722
|
+
const derived = config.withDerivedRows();
|
|
723
|
+
const rows = [];
|
|
724
|
+
for (const kind of config.borrowableKinds(slug)) for (const node of source.tree(kind)) {
|
|
725
|
+
const members = leafItems(node).filter((leaf) => config.canBorrow({
|
|
726
|
+
kind,
|
|
727
|
+
path: leaf.path,
|
|
728
|
+
slug
|
|
729
|
+
}).ok);
|
|
730
|
+
if (members.length === 0) continue;
|
|
731
|
+
let linked = 0;
|
|
732
|
+
let local = 0;
|
|
733
|
+
let shared = 0;
|
|
734
|
+
let sharedOrigin;
|
|
735
|
+
for (const leaf of members) {
|
|
736
|
+
const held = derived.resolve(kind, leaf.path);
|
|
737
|
+
if (!held) continue;
|
|
738
|
+
if (held.borrowedFrom === slug) {
|
|
739
|
+
linked += 1;
|
|
740
|
+
continue;
|
|
741
|
+
}
|
|
742
|
+
local += 1;
|
|
743
|
+
const origin = sharedWithOrigin({
|
|
744
|
+
config: derived,
|
|
745
|
+
source,
|
|
746
|
+
slug,
|
|
747
|
+
kind,
|
|
748
|
+
path: leaf.path
|
|
749
|
+
});
|
|
750
|
+
if (origin !== void 0) {
|
|
751
|
+
shared += 1;
|
|
752
|
+
sharedOrigin ??= origin;
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
rows.push({
|
|
756
|
+
kind,
|
|
757
|
+
path: node.path,
|
|
758
|
+
type: node.type,
|
|
759
|
+
name: node.item?.displayLabel ?? node.name,
|
|
760
|
+
members: members.length,
|
|
761
|
+
linked: linked === members.length,
|
|
762
|
+
replaces: local - shared,
|
|
763
|
+
shared,
|
|
764
|
+
...sharedOrigin === void 0 ? {} : { sharedOrigin }
|
|
765
|
+
});
|
|
766
|
+
}
|
|
767
|
+
return rows;
|
|
768
|
+
}
|
|
769
|
+
//#endregion
|
|
770
|
+
export { planBreak, planLink, planUnlink, sourceRowStates };
|