@getodk/xforms-engine 0.6.0 → 0.8.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/dist/client/BaseNode.d.ts +4 -4
- package/dist/client/BaseValueNode.d.ts +7 -3
- package/dist/client/RootNode.d.ts +20 -16
- package/dist/client/UploadNode.d.ts +53 -0
- package/dist/client/attachments/InstanceAttachmentMeta.d.ts +8 -0
- package/dist/client/attachments/InstanceAttachmentsConfig.d.ts +8 -0
- package/dist/client/constants.d.ts +11 -12
- package/dist/client/form/CreateFormInstance.d.ts +14 -0
- package/dist/client/form/EditFormInstance.d.ts +62 -0
- package/dist/client/form/FormInstance.d.ts +104 -0
- package/dist/client/form/FormInstanceConfig.d.ts +19 -0
- package/dist/client/form/FormResource.d.ts +1 -0
- package/dist/client/form/LoadForm.d.ts +79 -0
- package/dist/client/form/LoadFormResult.d.ts +67 -0
- package/dist/client/form/RestoreFormInstance.d.ts +8 -0
- package/dist/client/hierarchy.d.ts +4 -5
- package/dist/client/index.d.ts +40 -11
- package/dist/client/node-types.d.ts +2 -3
- package/dist/client/repeat/BaseRepeatRangeNode.d.ts +3 -4
- package/dist/client/repeat/RepeatInstanceNode.d.ts +4 -5
- package/dist/client/repeat/RepeatRangeControlledNode.d.ts +2 -2
- package/dist/client/repeat/RepeatRangeUncontrolledNode.d.ts +2 -2
- package/dist/client/resources.d.ts +1 -1
- package/dist/client/serialization/InstanceData.d.ts +14 -0
- package/dist/client/serialization/InstanceFile.d.ts +6 -0
- package/dist/client/serialization/InstancePayload.d.ts +93 -0
- package/dist/client/serialization/InstancePayloadOptions.d.ts +24 -0
- package/dist/client/serialization/InstanceState.d.ts +12 -0
- package/dist/client/submission/{SubmissionDefinition.d.ts → SubmissionMeta.d.ts} +1 -1
- package/dist/entrypoints/FormInstance.d.ts +20 -0
- package/dist/entrypoints/FormResult/BaseFormResult.d.ts +22 -0
- package/dist/entrypoints/FormResult/BaseInstantiableFormResult.d.ts +25 -0
- package/dist/entrypoints/FormResult/FormFailureResult.d.ts +17 -0
- package/dist/entrypoints/FormResult/FormSuccessResult.d.ts +15 -0
- package/dist/entrypoints/FormResult/FormWarningResult.d.ts +15 -0
- package/dist/entrypoints/createInstance.d.ts +9 -0
- package/dist/entrypoints/editInstance.d.ts +9 -0
- package/dist/entrypoints/index.d.ts +4 -0
- package/dist/entrypoints/loadForm.d.ts +4 -0
- package/dist/entrypoints/restoreInstance.d.ts +9 -0
- package/dist/error/LoadFormFailureError.d.ts +9 -0
- package/dist/error/MalformedInstanceDataError.d.ts +3 -0
- package/dist/error/TemplatedNodeAttributeSerializationError.d.ts +22 -0
- package/dist/error/UploadValueTypeError.d.ts +8 -0
- package/dist/index.d.ts +2 -33
- package/dist/index.js +8280 -6779
- package/dist/index.js.map +1 -1
- package/dist/instance/Group.d.ts +6 -5
- package/dist/instance/InputControl.d.ts +5 -4
- package/dist/instance/ModelValue.d.ts +5 -4
- package/dist/instance/Note.d.ts +4 -3
- package/dist/instance/PrimaryInstance.d.ts +34 -8
- package/dist/instance/RangeControl.d.ts +5 -4
- package/dist/instance/RankControl.d.ts +6 -5
- package/dist/instance/Root.d.ts +7 -9
- package/dist/instance/SelectControl.d.ts +4 -3
- package/dist/instance/Subtree.d.ts +6 -5
- package/dist/instance/TriggerControl.d.ts +4 -3
- package/dist/instance/UploadControl.d.ts +58 -0
- package/dist/instance/abstract/DescendantNode.d.ts +10 -1
- package/dist/instance/abstract/InstanceNode.d.ts +7 -4
- package/dist/instance/abstract/ValueNode.d.ts +7 -5
- package/dist/instance/attachments/InstanceAttachment.d.ts +42 -0
- package/dist/instance/attachments/InstanceAttachmentsState.d.ts +9 -0
- package/dist/instance/children/DescendantNodeInitOptions.d.ts +32 -0
- package/dist/instance/{children.d.ts → children/buildChildren.d.ts} +1 -1
- package/dist/instance/children/childrenInitOptions.d.ts +9 -0
- package/dist/instance/children/normalizeChildInitOptions.d.ts +2 -0
- package/dist/instance/hierarchy.d.ts +6 -7
- package/dist/instance/input/InitialInstanceState.d.ts +13 -0
- package/dist/instance/input/InstanceAttachmentMap.d.ts +19 -0
- package/dist/instance/internal-api/InstanceAttachmentContext.d.ts +19 -0
- package/dist/instance/internal-api/InstanceConfig.d.ts +4 -9
- package/dist/instance/internal-api/InstanceValueContext.d.ts +8 -1
- package/dist/instance/internal-api/serialization/ClientReactiveSerializableInstance.d.ts +16 -0
- package/dist/instance/internal-api/serialization/ClientReactiveSerializableLeafNode.d.ts +32 -0
- package/dist/instance/internal-api/serialization/ClientReactiveSerializableParentNode.d.ts +18 -0
- package/dist/instance/internal-api/serialization/ClientReactiveSerializableTemplatedNode.d.ts +13 -0
- package/dist/instance/internal-api/serialization/ClientReactiveSerializableValueNode.d.ts +21 -0
- package/dist/instance/repeat/BaseRepeatRange.d.ts +10 -8
- package/dist/instance/repeat/RepeatInstance.d.ts +10 -7
- package/dist/instance/repeat/RepeatRangeControlled.d.ts +27 -3
- package/dist/instance/repeat/RepeatRangeUncontrolled.d.ts +4 -3
- package/dist/instance/resource.d.ts +5 -1
- package/dist/integration/xpath/EngineXPathEvaluator.d.ts +2 -2
- package/dist/integration/xpath/adapter/kind.d.ts +4 -10
- package/dist/integration/xpath/static-dom/StaticAttribute.d.ts +4 -5
- package/dist/integration/xpath/static-dom/StaticDocument.d.ts +13 -10
- package/dist/integration/xpath/static-dom/StaticElement.d.ts +21 -22
- package/dist/integration/xpath/static-dom/StaticNode.d.ts +1 -1
- package/dist/integration/xpath/static-dom/StaticParentNode.d.ts +13 -0
- package/dist/integration/xpath/static-dom/staticNodeName.d.ts +3 -0
- package/dist/lib/client-reactivity/instance-state/createNodeRangeInstanceState.d.ts +4 -0
- package/dist/lib/client-reactivity/instance-state/createParentNodeInstanceState.d.ts +4 -0
- package/dist/lib/client-reactivity/instance-state/createPrimaryInstanceState.d.ts +3 -0
- package/dist/lib/client-reactivity/instance-state/createRootInstanceState.d.ts +3 -0
- package/dist/lib/client-reactivity/instance-state/createTemplatedNodeInstanceState.d.ts +6 -0
- package/dist/lib/client-reactivity/instance-state/createValueNodeInstanceState.d.ts +3 -0
- package/dist/lib/client-reactivity/instance-state/prepareInstancePayload.d.ts +8 -0
- package/dist/lib/names/UnprefixedXFormsName.d.ts +4 -0
- package/dist/lib/reactivity/createInstanceAttachment.d.ts +8 -0
- package/dist/lib/reactivity/createInstanceValueState.d.ts +2 -27
- package/dist/lib/resource-helpers.d.ts +2 -0
- package/dist/parse/XFormDOM.d.ts +1 -1
- package/dist/parse/body/BodyDefinition.d.ts +2 -1
- package/dist/parse/body/control/UploadControlDefinition.d.ts +2 -0
- package/dist/parse/model/BindDefinition.d.ts +1 -1
- package/dist/parse/model/BindTypeDefinition.d.ts +2 -7
- package/dist/parse/model/ItextTranslationsDefinition.d.ts +18 -0
- package/dist/parse/model/LeafNodeDefinition.d.ts +4 -5
- package/dist/parse/model/ModelBindMap.d.ts +1 -1
- package/dist/parse/model/ModelDefinition.d.ts +9 -2
- package/dist/parse/model/NodeDefinition.d.ts +18 -30
- package/dist/parse/model/NoteNodeDefinition.d.ts +3 -2
- package/dist/parse/model/RangeNodeDefinition.d.ts +2 -1
- package/dist/parse/model/RepeatDefinition.d.ts +62 -0
- package/dist/parse/model/RootAttributeDefinition.d.ts +1 -4
- package/dist/parse/model/RootAttributeMap.d.ts +2 -1
- package/dist/parse/model/RootDefinition.d.ts +7 -8
- package/dist/parse/model/SecondaryInstance/SecondaryInstancesDefinition.d.ts +15 -2
- package/dist/parse/model/SecondaryInstance/assertSecondaryInstanceDefinition.d.ts +5 -0
- package/dist/parse/model/SecondaryInstance/defineSecondaryInstance.d.ts +5 -0
- package/dist/parse/model/SecondaryInstance/sources/BlankSecondaryInstanceSource.d.ts +1 -7
- package/dist/parse/model/SecondaryInstance/sources/CSVExternalSecondaryInstance.d.ts +1 -1
- package/dist/parse/model/SecondaryInstance/sources/GeoJSONExternalSecondaryInstance.d.ts +1 -1
- package/dist/parse/model/SecondaryInstance/sources/InternalSecondaryInstanceSource.d.ts +1 -1
- package/dist/parse/model/SecondaryInstance/sources/SecondaryInstanceSource.d.ts +1 -1
- package/dist/parse/model/SecondaryInstance/sources/XMLExternalSecondaryInstanceSource.d.ts +1 -1
- package/dist/parse/model/{FormSubmissionDefinition.d.ts → SubmissionDefinition.d.ts} +2 -2
- package/dist/parse/model/SubtreeDefinition.d.ts +4 -5
- package/dist/parse/model/nodeDefinitionMap.d.ts +5 -0
- package/dist/parse/shared/parseInstanceXML.d.ts +21 -0
- package/dist/parse/shared/parseStaticDocumentFromDOMSubtree.d.ts +4 -21
- package/dist/solid.js +8251 -6751
- package/dist/solid.js.map +1 -1
- package/package.json +15 -14
- package/src/client/BaseNode.ts +4 -4
- package/src/client/BaseValueNode.ts +7 -3
- package/src/client/RootNode.ts +32 -19
- package/src/client/UploadNode.ts +78 -0
- package/src/client/attachments/InstanceAttachmentMeta.ts +10 -0
- package/src/client/attachments/InstanceAttachmentsConfig.ts +13 -0
- package/src/client/constants.ts +12 -14
- package/src/client/form/CreateFormInstance.ts +19 -0
- package/src/client/form/EditFormInstance.ts +93 -0
- package/src/client/form/FormInstance.ts +114 -0
- package/src/client/form/FormInstanceConfig.ts +21 -0
- package/src/client/form/FormResource.ts +1 -0
- package/src/client/form/LoadForm.ts +92 -0
- package/src/client/form/LoadFormResult.ts +103 -0
- package/src/client/form/RestoreFormInstance.ts +14 -0
- package/src/client/hierarchy.ts +5 -8
- package/src/client/index.ts +49 -29
- package/src/client/node-types.ts +3 -8
- package/src/client/repeat/BaseRepeatRangeNode.ts +3 -4
- package/src/client/repeat/RepeatInstanceNode.ts +4 -8
- package/src/client/repeat/RepeatRangeControlledNode.ts +2 -2
- package/src/client/repeat/RepeatRangeUncontrolledNode.ts +2 -2
- package/src/client/resources.ts +2 -2
- package/src/client/serialization/InstanceData.ts +24 -0
- package/src/client/serialization/InstanceFile.ts +9 -0
- package/src/client/serialization/InstancePayload.ts +126 -0
- package/src/client/serialization/InstancePayloadOptions.ts +29 -0
- package/src/client/serialization/InstanceState.ts +14 -0
- package/src/client/submission/{SubmissionDefinition.ts → SubmissionMeta.ts} +1 -1
- package/src/entrypoints/FormInstance.ts +56 -0
- package/src/entrypoints/FormResult/BaseFormResult.ts +40 -0
- package/src/entrypoints/FormResult/BaseInstantiableFormResult.ts +109 -0
- package/src/entrypoints/FormResult/FormFailureResult.ts +44 -0
- package/src/entrypoints/FormResult/FormSuccessResult.ts +25 -0
- package/src/entrypoints/FormResult/FormWarningResult.ts +25 -0
- package/src/entrypoints/createInstance.ts +23 -0
- package/src/entrypoints/editInstance.ts +24 -0
- package/src/entrypoints/index.ts +4 -0
- package/src/entrypoints/loadForm.ts +154 -0
- package/src/entrypoints/restoreInstance.ts +27 -0
- package/src/error/LoadFormFailureError.ts +114 -0
- package/src/error/MalformedInstanceDataError.ts +3 -0
- package/src/error/TemplatedNodeAttributeSerializationError.ts +24 -0
- package/src/error/UploadValueTypeError.ts +13 -0
- package/src/index.ts +2 -46
- package/src/instance/Group.ts +16 -15
- package/src/instance/InputControl.ts +17 -11
- package/src/instance/ModelValue.ts +17 -11
- package/src/instance/Note.ts +10 -9
- package/src/instance/PrimaryInstance.ts +68 -31
- package/src/instance/RangeControl.ts +17 -11
- package/src/instance/RankControl.ts +28 -19
- package/src/instance/Root.ts +20 -31
- package/src/instance/SelectControl.ts +21 -12
- package/src/instance/Subtree.ts +16 -15
- package/src/instance/TriggerControl.ts +21 -12
- package/src/instance/UploadControl.ts +184 -0
- package/src/instance/abstract/DescendantNode.ts +12 -2
- package/src/instance/abstract/InstanceNode.ts +9 -5
- package/src/instance/abstract/ValueNode.ts +11 -13
- package/src/instance/attachments/InstanceAttachment.ts +69 -0
- package/src/instance/attachments/InstanceAttachmentsState.ts +18 -0
- package/src/instance/children/DescendantNodeInitOptions.ts +35 -0
- package/src/instance/{children.ts → children/buildChildren.ts} +57 -53
- package/src/instance/children/childrenInitOptions.ts +117 -0
- package/src/instance/children/normalizeChildInitOptions.ts +332 -0
- package/src/instance/hierarchy.ts +6 -9
- package/src/instance/input/InitialInstanceState.ts +108 -0
- package/src/instance/input/InstanceAttachmentMap.ts +154 -0
- package/src/instance/internal-api/InstanceAttachmentContext.ts +20 -0
- package/src/instance/internal-api/InstanceConfig.ts +6 -10
- package/src/instance/internal-api/InstanceValueContext.ts +9 -1
- package/src/instance/internal-api/serialization/ClientReactiveSerializableInstance.ts +22 -0
- package/src/instance/internal-api/serialization/ClientReactiveSerializableLeafNode.ts +43 -0
- package/src/instance/internal-api/serialization/ClientReactiveSerializableParentNode.ts +26 -0
- package/src/instance/internal-api/serialization/ClientReactiveSerializableTemplatedNode.ts +24 -0
- package/src/instance/internal-api/serialization/ClientReactiveSerializableValueNode.ts +28 -0
- package/src/instance/repeat/BaseRepeatRange.ts +19 -24
- package/src/instance/repeat/RepeatInstance.ts +26 -19
- package/src/instance/repeat/RepeatRangeControlled.ts +90 -17
- package/src/instance/repeat/RepeatRangeUncontrolled.ts +10 -9
- package/src/instance/resource.ts +14 -1
- package/src/integration/xpath/EngineXPathEvaluator.ts +2 -2
- package/src/integration/xpath/adapter/kind.ts +1 -28
- package/src/integration/xpath/adapter/traversal.ts +2 -2
- package/src/integration/xpath/static-dom/StaticAttribute.ts +6 -5
- package/src/integration/xpath/static-dom/StaticDocument.ts +17 -16
- package/src/integration/xpath/static-dom/StaticElement.ts +196 -50
- package/src/integration/xpath/static-dom/StaticNode.ts +1 -1
- package/src/integration/xpath/static-dom/StaticParentNode.ts +22 -0
- package/src/integration/xpath/static-dom/staticNodeName.ts +20 -0
- package/src/lib/client-reactivity/instance-state/createNodeRangeInstanceState.ts +17 -0
- package/src/lib/client-reactivity/instance-state/createParentNodeInstanceState.ts +22 -0
- package/src/lib/client-reactivity/instance-state/createPrimaryInstanceState.ts +12 -0
- package/src/lib/client-reactivity/{submission/createRootSubmissionState.ts → instance-state/createRootInstanceState.ts} +4 -4
- package/src/lib/client-reactivity/instance-state/createTemplatedNodeInstanceState.ts +31 -0
- package/src/lib/client-reactivity/instance-state/createValueNodeInstanceState.ts +21 -0
- package/src/lib/client-reactivity/instance-state/prepareInstancePayload.ts +237 -0
- package/src/lib/names/UnprefixedXFormsName.ts +12 -0
- package/src/lib/reactivity/createInstanceAttachment.ts +212 -0
- package/src/lib/reactivity/createInstanceValueState.ts +27 -51
- package/src/lib/resource-helpers.ts +33 -0
- package/src/parse/XFormDOM.ts +1 -3
- package/src/parse/body/BodyDefinition.ts +4 -0
- package/src/parse/body/control/UploadControlDefinition.ts +42 -0
- package/src/parse/model/BindDefinition.ts +1 -1
- package/src/parse/model/BindTypeDefinition.ts +68 -26
- package/src/parse/model/ItextTranslationsDefinition.ts +79 -0
- package/src/parse/model/LeafNodeDefinition.ts +3 -5
- package/src/parse/model/ModelBindMap.ts +0 -5
- package/src/parse/model/ModelDefinition.ts +36 -3
- package/src/parse/model/NodeDefinition.ts +19 -45
- package/src/parse/model/NoteNodeDefinition.ts +4 -3
- package/src/parse/model/RangeNodeDefinition.ts +3 -2
- package/src/parse/model/RepeatDefinition.ts +382 -0
- package/src/parse/model/RootAttributeDefinition.ts +6 -7
- package/src/parse/model/RootAttributeMap.ts +15 -10
- package/src/parse/model/RootDefinition.ts +17 -19
- package/src/parse/model/SecondaryInstance/SecondaryInstancesDefinition.ts +23 -2
- package/src/parse/model/SecondaryInstance/assertSecondaryInstanceDefinition.ts +14 -0
- package/src/parse/model/SecondaryInstance/defineSecondaryInstance.ts +32 -0
- package/src/parse/model/SecondaryInstance/sources/BlankSecondaryInstanceSource.ts +3 -24
- package/src/parse/model/SecondaryInstance/sources/CSVExternalSecondaryInstance.ts +33 -86
- package/src/parse/model/SecondaryInstance/sources/ExternalSecondaryInstanceResource.ts +1 -30
- package/src/parse/model/SecondaryInstance/sources/GeoJSONExternalSecondaryInstance.ts +64 -137
- package/src/parse/model/SecondaryInstance/sources/InternalSecondaryInstanceSource.ts +9 -7
- package/src/parse/model/SecondaryInstance/sources/SecondaryInstanceSource.ts +1 -1
- package/src/parse/model/SecondaryInstance/sources/XMLExternalSecondaryInstanceSource.ts +7 -7
- package/src/parse/model/{FormSubmissionDefinition.ts → SubmissionDefinition.ts} +2 -2
- package/src/parse/model/SubtreeDefinition.ts +4 -5
- package/src/parse/model/nodeDefinitionMap.ts +34 -0
- package/src/parse/shared/parseInstanceXML.ts +79 -0
- package/src/parse/shared/parseStaticDocumentFromDOMSubtree.ts +45 -130
- package/dist/client/EngineConfig.d.ts +0 -79
- package/dist/client/submission/SubmissionData.d.ts +0 -7
- package/dist/client/submission/SubmissionInstanceFile.d.ts +0 -6
- package/dist/client/submission/SubmissionOptions.d.ts +0 -23
- package/dist/client/submission/SubmissionResult.d.ts +0 -91
- package/dist/client/submission/SubmissionState.d.ts +0 -12
- package/dist/client/unsupported/UnsupportedControlNode.d.ts +0 -30
- package/dist/client/unsupported/UploadNode.d.ts +0 -9
- package/dist/instance/abstract/UnsupportedControl.d.ts +0 -54
- package/dist/instance/index.d.ts +0 -8
- package/dist/instance/internal-api/ValueContext.d.ts +0 -23
- package/dist/instance/internal-api/submission/ClientReactiveSubmittableInstance.d.ts +0 -14
- package/dist/instance/internal-api/submission/ClientReactiveSubmittableLeafNode.d.ts +0 -32
- package/dist/instance/internal-api/submission/ClientReactiveSubmittableParentNode.d.ts +0 -19
- package/dist/instance/internal-api/submission/ClientReactiveSubmittableValueNode.d.ts +0 -18
- package/dist/instance/unsupported/UploadControl.d.ts +0 -6
- package/dist/lib/client-reactivity/submission/createInstanceSubmissionState.d.ts +0 -3
- package/dist/lib/client-reactivity/submission/createLeafNodeSubmissionState.d.ts +0 -3
- package/dist/lib/client-reactivity/submission/createNodeRangeSubmissionState.d.ts +0 -4
- package/dist/lib/client-reactivity/submission/createParentNodeSubmissionState.d.ts +0 -4
- package/dist/lib/client-reactivity/submission/createRootSubmissionState.d.ts +0 -3
- package/dist/lib/client-reactivity/submission/createValueNodeSubmissionState.d.ts +0 -3
- package/dist/lib/client-reactivity/submission/prepareSubmission.d.ts +0 -8
- package/dist/lib/reactivity/createValueState.d.ts +0 -40
- package/dist/parse/model/ItextTranslation/ItextTranslationDefinition.d.ts +0 -4
- package/dist/parse/model/ItextTranslation/ItextTranslationRootDefinition.d.ts +0 -9
- package/dist/parse/model/ItextTranslation/ItextTranslationsDefinition.d.ts +0 -8
- package/dist/parse/model/RepeatInstanceDefinition.d.ts +0 -17
- package/dist/parse/model/RepeatRangeDefinition.d.ts +0 -32
- package/dist/parse/model/RepeatTemplateDefinition.d.ts +0 -31
- package/dist/parse/model/SecondaryInstance/SecondaryInstanceDefinition.d.ts +0 -4
- package/dist/parse/model/SecondaryInstance/SecondaryInstanceRootDefinition.d.ts +0 -7
- package/src/client/EngineConfig.ts +0 -84
- package/src/client/submission/SubmissionData.ts +0 -12
- package/src/client/submission/SubmissionInstanceFile.ts +0 -9
- package/src/client/submission/SubmissionOptions.ts +0 -28
- package/src/client/submission/SubmissionResult.ts +0 -124
- package/src/client/submission/SubmissionState.ts +0 -14
- package/src/client/unsupported/UnsupportedControlNode.ts +0 -36
- package/src/client/unsupported/UploadNode.ts +0 -14
- package/src/instance/abstract/UnsupportedControl.ts +0 -175
- package/src/instance/index.ts +0 -55
- package/src/instance/internal-api/ValueContext.ts +0 -28
- package/src/instance/internal-api/submission/ClientReactiveSubmittableInstance.ts +0 -20
- package/src/instance/internal-api/submission/ClientReactiveSubmittableLeafNode.ts +0 -43
- package/src/instance/internal-api/submission/ClientReactiveSubmittableParentNode.ts +0 -26
- package/src/instance/internal-api/submission/ClientReactiveSubmittableValueNode.ts +0 -24
- package/src/instance/unsupported/UploadControl.ts +0 -9
- package/src/lib/client-reactivity/submission/createInstanceSubmissionState.ts +0 -12
- package/src/lib/client-reactivity/submission/createLeafNodeSubmissionState.ts +0 -20
- package/src/lib/client-reactivity/submission/createNodeRangeSubmissionState.ts +0 -17
- package/src/lib/client-reactivity/submission/createParentNodeSubmissionState.ts +0 -22
- package/src/lib/client-reactivity/submission/createValueNodeSubmissionState.ts +0 -21
- package/src/lib/client-reactivity/submission/prepareSubmission.ts +0 -172
- package/src/lib/reactivity/createValueState.ts +0 -200
- package/src/parse/model/ItextTranslation/ItextTranslationDefinition.ts +0 -4
- package/src/parse/model/ItextTranslation/ItextTranslationRootDefinition.ts +0 -42
- package/src/parse/model/ItextTranslation/ItextTranslationsDefinition.ts +0 -31
- package/src/parse/model/RepeatInstanceDefinition.ts +0 -38
- package/src/parse/model/RepeatRangeDefinition.ts +0 -98
- package/src/parse/model/RepeatTemplateDefinition.ts +0 -149
- package/src/parse/model/SecondaryInstance/SecondaryInstanceDefinition.ts +0 -4
- package/src/parse/model/SecondaryInstance/SecondaryInstanceRootDefinition.ts +0 -12
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { InstanceState } from '../../../client/serialization/InstanceState.ts';
|
|
2
|
+
import type { ClientReactiveSerializableValueNode } from '../../../instance/internal-api/serialization/ClientReactiveSerializableValueNode.ts';
|
|
3
|
+
import { escapeXMLText, serializeLeafElementXML } from '../../xml-serialization.ts';
|
|
4
|
+
|
|
5
|
+
export const createValueNodeInstanceState = (
|
|
6
|
+
node: ClientReactiveSerializableValueNode
|
|
7
|
+
): InstanceState => {
|
|
8
|
+
const { qualifiedName } = node.definition;
|
|
9
|
+
|
|
10
|
+
return {
|
|
11
|
+
get instanceXML() {
|
|
12
|
+
if (!node.currentState.relevant) {
|
|
13
|
+
return '';
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const xmlValue = escapeXMLText(node.currentState.instanceValue);
|
|
17
|
+
|
|
18
|
+
return serializeLeafElementXML(qualifiedName, xmlValue);
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
};
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
import { UnreachableError } from '@getodk/common/lib/error/UnreachableError.ts';
|
|
2
|
+
import { bestFitDecreasing } from 'bin-packer';
|
|
3
|
+
import { INSTANCE_FILE_NAME, INSTANCE_FILE_TYPE } from '../../../client/constants.ts';
|
|
4
|
+
import type { InstanceData as ClientInstanceData } from '../../../client/serialization/InstanceData.ts';
|
|
5
|
+
import type { InstanceFile as ClientInstanceFile } from '../../../client/serialization/InstanceFile.ts';
|
|
6
|
+
import type {
|
|
7
|
+
ChunkedInstancePayload,
|
|
8
|
+
InstancePayload,
|
|
9
|
+
MonolithicInstancePayload,
|
|
10
|
+
} from '../../../client/serialization/InstancePayload.ts';
|
|
11
|
+
import type { InstancePayloadType } from '../../../client/serialization/InstancePayloadOptions.ts';
|
|
12
|
+
import type { SubmissionMeta } from '../../../client/submission/SubmissionMeta.ts';
|
|
13
|
+
import type { DescendantNodeViolationReference } from '../../../client/validation.ts';
|
|
14
|
+
import { ErrorProductionDesignPendingError } from '../../../error/ErrorProductionDesignPendingError.ts';
|
|
15
|
+
import type { InstanceAttachmentsState } from '../../../instance/attachments/InstanceAttachmentsState.ts';
|
|
16
|
+
import type { ClientReactiveSerializableInstance } from '../../../instance/internal-api/serialization/ClientReactiveSerializableInstance.ts';
|
|
17
|
+
|
|
18
|
+
const collectInstanceAttachmentFiles = (attachments: InstanceAttachmentsState): readonly File[] => {
|
|
19
|
+
const files = Array.from(attachments.entries()).map(([context, attachment]) => {
|
|
20
|
+
if (!context.isAttached() || !context.isRelevant()) {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return attachment.getValue();
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
return files.filter((file) => file != null);
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
class InstanceFile extends File implements ClientInstanceFile {
|
|
31
|
+
override readonly name = INSTANCE_FILE_NAME;
|
|
32
|
+
override readonly type = INSTANCE_FILE_TYPE;
|
|
33
|
+
|
|
34
|
+
constructor(instanceRoot: ClientReactiveSerializableInstance) {
|
|
35
|
+
const { instanceXML } = instanceRoot.instanceState;
|
|
36
|
+
|
|
37
|
+
super([instanceXML], INSTANCE_FILE_NAME, {
|
|
38
|
+
type: INSTANCE_FILE_TYPE,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
type AssertFile = (value: FormDataEntryValue) => asserts value is File;
|
|
44
|
+
|
|
45
|
+
const assertFile: AssertFile = (value) => {
|
|
46
|
+
if (!(value instanceof File)) {
|
|
47
|
+
throw new ErrorProductionDesignPendingError('Expected an instance of File');
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
type AssertInstanceData = (data: FormData) => asserts data is ClientInstanceData;
|
|
52
|
+
|
|
53
|
+
const assertInstanceData: AssertInstanceData = (data) => {
|
|
54
|
+
let instanceFile: File | null = null;
|
|
55
|
+
|
|
56
|
+
for (const [key, value] of data.entries()) {
|
|
57
|
+
assertFile(value);
|
|
58
|
+
|
|
59
|
+
if (key === INSTANCE_FILE_NAME) {
|
|
60
|
+
instanceFile = value;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (!(instanceFile instanceof InstanceFile)) {
|
|
65
|
+
throw new Error(`Invalid InstanceData`);
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
class InstanceData extends FormData {
|
|
70
|
+
static from(instanceFile: InstanceFile, attachments: readonly File[]): ClientInstanceData {
|
|
71
|
+
const data = new this(instanceFile, attachments);
|
|
72
|
+
|
|
73
|
+
assertInstanceData(data);
|
|
74
|
+
|
|
75
|
+
return data;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
private constructor(
|
|
79
|
+
readonly instanceFile: InstanceFile,
|
|
80
|
+
readonly attachments: readonly File[]
|
|
81
|
+
) {
|
|
82
|
+
super();
|
|
83
|
+
|
|
84
|
+
this.set(INSTANCE_FILE_NAME, instanceFile);
|
|
85
|
+
|
|
86
|
+
attachments.forEach((attachment) => {
|
|
87
|
+
const { name } = attachment;
|
|
88
|
+
|
|
89
|
+
if (name === INSTANCE_FILE_NAME && attachment !== instanceFile) {
|
|
90
|
+
throw new Error(`Failed to add conflicting attachment with name ${INSTANCE_FILE_NAME}`);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
this.set(name, attachment);
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
interface PendingValidation {
|
|
99
|
+
readonly status: 'pending';
|
|
100
|
+
readonly violations: readonly DescendantNodeViolationReference[];
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
interface ReadyValidation {
|
|
104
|
+
readonly status: 'ready';
|
|
105
|
+
readonly violations: null;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
type InstanceStateValidation = PendingValidation | ReadyValidation;
|
|
109
|
+
|
|
110
|
+
const validateInstance = (
|
|
111
|
+
instanceRoot: ClientReactiveSerializableInstance
|
|
112
|
+
): InstanceStateValidation => {
|
|
113
|
+
const { violations } = instanceRoot.validationState;
|
|
114
|
+
|
|
115
|
+
if (violations.length === 0) {
|
|
116
|
+
return {
|
|
117
|
+
status: 'ready',
|
|
118
|
+
violations: null,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return {
|
|
123
|
+
status: 'pending',
|
|
124
|
+
violations,
|
|
125
|
+
};
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
const monolithicInstancePayload = (
|
|
129
|
+
validation: InstanceStateValidation,
|
|
130
|
+
submissionMeta: SubmissionMeta,
|
|
131
|
+
instanceFile: InstanceFile,
|
|
132
|
+
attachments: readonly File[]
|
|
133
|
+
): MonolithicInstancePayload => {
|
|
134
|
+
const data = InstanceData.from(instanceFile, attachments);
|
|
135
|
+
|
|
136
|
+
return {
|
|
137
|
+
payloadType: 'monolithic',
|
|
138
|
+
...validation,
|
|
139
|
+
submissionMeta,
|
|
140
|
+
data: [data],
|
|
141
|
+
};
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
interface ChunkedInstancePayloadOptions {
|
|
145
|
+
readonly maxSize: number;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
type PartitionedInstanceData = readonly [ClientInstanceData, ...ClientInstanceData[]];
|
|
149
|
+
|
|
150
|
+
const partitionInstanceData = (
|
|
151
|
+
instanceFile: InstanceFile,
|
|
152
|
+
attachments: readonly File[],
|
|
153
|
+
options: ChunkedInstancePayloadOptions
|
|
154
|
+
): PartitionedInstanceData => {
|
|
155
|
+
const { maxSize } = options;
|
|
156
|
+
const maxAttachmentSize = maxSize - instanceFile.size;
|
|
157
|
+
const { bins, oversized } = bestFitDecreasing(
|
|
158
|
+
attachments,
|
|
159
|
+
(attachment) => {
|
|
160
|
+
return attachment.size;
|
|
161
|
+
},
|
|
162
|
+
maxAttachmentSize
|
|
163
|
+
);
|
|
164
|
+
|
|
165
|
+
const errors = oversized.map((attachment) => {
|
|
166
|
+
return new Error(
|
|
167
|
+
`Combined size of instance XML (${instanceFile.size}) and attachment (${attachment.size}) exceeds maxSize (${maxSize}).`
|
|
168
|
+
);
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
if (errors.length > 0) {
|
|
172
|
+
throw new AggregateError(errors, 'Failed to produce chunked instance payload');
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const [
|
|
176
|
+
// Ensure at least one `InstanceData` is produced, in case there are no
|
|
177
|
+
// attachments present at all
|
|
178
|
+
head = InstanceData.from(instanceFile, []),
|
|
179
|
+
...tail
|
|
180
|
+
] = bins.map((bin) => InstanceData.from(instanceFile, bin));
|
|
181
|
+
|
|
182
|
+
return [head, ...tail];
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
const chunkedInstancePayload = (
|
|
186
|
+
validation: InstanceStateValidation,
|
|
187
|
+
submissionMeta: SubmissionMeta,
|
|
188
|
+
instanceFile: InstanceFile,
|
|
189
|
+
attachments: readonly File[],
|
|
190
|
+
options: ChunkedInstancePayloadOptions
|
|
191
|
+
): ChunkedInstancePayload => {
|
|
192
|
+
const data = partitionInstanceData(instanceFile, attachments, options);
|
|
193
|
+
|
|
194
|
+
return {
|
|
195
|
+
payloadType: 'chunked',
|
|
196
|
+
...validation,
|
|
197
|
+
submissionMeta,
|
|
198
|
+
data,
|
|
199
|
+
};
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
export interface PrepareInstancePayloadOptions<PayloadType extends InstancePayloadType> {
|
|
203
|
+
readonly payloadType: PayloadType;
|
|
204
|
+
readonly maxSize: number;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
export const prepareInstancePayload = <PayloadType extends InstancePayloadType>(
|
|
208
|
+
instanceRoot: ClientReactiveSerializableInstance,
|
|
209
|
+
options: PrepareInstancePayloadOptions<PayloadType>
|
|
210
|
+
): InstancePayload<PayloadType> => {
|
|
211
|
+
const validation = validateInstance(instanceRoot);
|
|
212
|
+
const submissionMeta = instanceRoot.definition.submission;
|
|
213
|
+
const instanceFile = new InstanceFile(instanceRoot);
|
|
214
|
+
const attachments = collectInstanceAttachmentFiles(instanceRoot.attachments);
|
|
215
|
+
|
|
216
|
+
switch (options.payloadType) {
|
|
217
|
+
case 'chunked':
|
|
218
|
+
return chunkedInstancePayload(
|
|
219
|
+
validation,
|
|
220
|
+
submissionMeta,
|
|
221
|
+
instanceFile,
|
|
222
|
+
attachments,
|
|
223
|
+
options
|
|
224
|
+
) satisfies ChunkedInstancePayload as InstancePayload<PayloadType>;
|
|
225
|
+
|
|
226
|
+
case 'monolithic':
|
|
227
|
+
return monolithicInstancePayload(
|
|
228
|
+
validation,
|
|
229
|
+
submissionMeta,
|
|
230
|
+
instanceFile,
|
|
231
|
+
attachments
|
|
232
|
+
) satisfies MonolithicInstancePayload as InstancePayload<PayloadType>;
|
|
233
|
+
|
|
234
|
+
default:
|
|
235
|
+
throw new UnreachableError(options.payloadType);
|
|
236
|
+
}
|
|
237
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { XFORMS_NAMESPACE_URI } from '@getodk/common/constants/xmlns.ts';
|
|
2
|
+
import { QualifiedName } from './QualifiedName.ts';
|
|
3
|
+
|
|
4
|
+
export class UnprefixedXFormsName extends QualifiedName {
|
|
5
|
+
constructor(localName: string) {
|
|
6
|
+
super({
|
|
7
|
+
namespaceURI: XFORMS_NAMESPACE_URI,
|
|
8
|
+
prefix: null,
|
|
9
|
+
localName,
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import { createMemo, createSignal } from 'solid-js';
|
|
2
|
+
import type { FormNodeID } from '../../client/identity.ts';
|
|
3
|
+
import { ErrorProductionDesignPendingError } from '../../error/ErrorProductionDesignPendingError.ts';
|
|
4
|
+
import type { InstanceAttachmentFileName } from '../../instance/attachments/InstanceAttachment.ts';
|
|
5
|
+
import { InstanceAttachment } from '../../instance/attachments/InstanceAttachment.ts';
|
|
6
|
+
import type { InstanceAttachmentContext } from '../../instance/internal-api/InstanceAttachmentContext.ts';
|
|
7
|
+
import type { DecodeInstanceValue } from '../../instance/internal-api/InstanceValueContext.ts';
|
|
8
|
+
import type { SimpleAtomicStateSetter } from './types.ts';
|
|
9
|
+
|
|
10
|
+
type FileNameExtension = `.${string}`;
|
|
11
|
+
|
|
12
|
+
type AssertFileNameExtension = (value: string) => asserts value is FileNameExtension;
|
|
13
|
+
|
|
14
|
+
const assertFileNameExtension: AssertFileNameExtension = (value) => {
|
|
15
|
+
if (!value.startsWith('.')) {
|
|
16
|
+
throw new ErrorProductionDesignPendingError('Expected file name extension to start with "."');
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
interface SplitFileNameResult {
|
|
21
|
+
readonly basename: string;
|
|
22
|
+
readonly extension: FileNameExtension | null;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const EXTENSION_PATTERN = /\.[^.]+?$/;
|
|
26
|
+
|
|
27
|
+
interface SearchPatternResult extends Array<string> {
|
|
28
|
+
readonly 0?: string;
|
|
29
|
+
readonly index?: number;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const searchPattern = (pattern: RegExp, string: string): SearchPatternResult => {
|
|
33
|
+
return pattern.exec(string) ?? [];
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const splitFileName = (fileName: string): SplitFileNameResult => {
|
|
37
|
+
const extensionMatches = searchPattern(EXTENSION_PATTERN, fileName);
|
|
38
|
+
const [extension = null] = extensionMatches;
|
|
39
|
+
const basename = fileName.slice(0, extensionMatches.index);
|
|
40
|
+
|
|
41
|
+
if (extension == null) {
|
|
42
|
+
return {
|
|
43
|
+
basename,
|
|
44
|
+
extension,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
assertFileNameExtension(extension);
|
|
49
|
+
|
|
50
|
+
return {
|
|
51
|
+
basename,
|
|
52
|
+
extension,
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
export type InstanceAttachmentRuntimeValue = File | null;
|
|
57
|
+
|
|
58
|
+
export type InstanceAttachmentFormDataEntry = readonly [
|
|
59
|
+
key: InstanceAttachmentFileName,
|
|
60
|
+
value: NonNullable<InstanceAttachmentRuntimeValue>,
|
|
61
|
+
];
|
|
62
|
+
|
|
63
|
+
interface InstanceAttachmentValueOptions {
|
|
64
|
+
readonly nodeId: FormNodeID;
|
|
65
|
+
readonly writtenAt: Date | null;
|
|
66
|
+
readonly file: InstanceAttachmentRuntimeValue;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
interface BaseInstanceAttachmentState {
|
|
70
|
+
readonly computedName: string | null;
|
|
71
|
+
readonly intrinsicName: string | null;
|
|
72
|
+
readonly file: InstanceAttachmentRuntimeValue;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
interface BlankInstanceAttachmentState extends BaseInstanceAttachmentState {
|
|
76
|
+
readonly computedName: null;
|
|
77
|
+
readonly intrinsicName: null;
|
|
78
|
+
readonly file: null;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
interface NonBlankInstanceAttachmentState extends BaseInstanceAttachmentState {
|
|
82
|
+
readonly computedName: string | null;
|
|
83
|
+
readonly intrinsicName: string;
|
|
84
|
+
readonly file: NonNullable<InstanceAttachmentRuntimeValue>;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// prettier-ignore
|
|
88
|
+
type InstanceAttachmentState =
|
|
89
|
+
| BlankInstanceAttachmentState
|
|
90
|
+
| NonBlankInstanceAttachmentState;
|
|
91
|
+
|
|
92
|
+
const instanceAttachmentState = (
|
|
93
|
+
context: InstanceAttachmentContext,
|
|
94
|
+
options: InstanceAttachmentValueOptions
|
|
95
|
+
): InstanceAttachmentState => {
|
|
96
|
+
const { nodeId, file, writtenAt } = options;
|
|
97
|
+
|
|
98
|
+
// No file -> no intrinsic name, no name to compute
|
|
99
|
+
if (file == null) {
|
|
100
|
+
return {
|
|
101
|
+
computedName: null,
|
|
102
|
+
intrinsicName: null,
|
|
103
|
+
file: null,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const intrinsicName = file.name;
|
|
108
|
+
|
|
109
|
+
// File exists, not written by client -> preserve instance input name
|
|
110
|
+
if (writtenAt == null) {
|
|
111
|
+
return {
|
|
112
|
+
computedName: null,
|
|
113
|
+
intrinsicName,
|
|
114
|
+
file,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// File was written by client, name is computed as configured by client
|
|
119
|
+
const { basename, extension } = splitFileName(intrinsicName);
|
|
120
|
+
const computedName = context.instanceConfig.computeAttachmentName({
|
|
121
|
+
nodeId,
|
|
122
|
+
writtenAt,
|
|
123
|
+
basename,
|
|
124
|
+
extension,
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
return {
|
|
128
|
+
computedName,
|
|
129
|
+
intrinsicName,
|
|
130
|
+
file,
|
|
131
|
+
};
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
export const createInstanceAttachment = (
|
|
135
|
+
context: InstanceAttachmentContext
|
|
136
|
+
): InstanceAttachment => {
|
|
137
|
+
return context.scope.runTask(() => {
|
|
138
|
+
const { rootDocument, nodeId } = context;
|
|
139
|
+
const { attachments } = rootDocument;
|
|
140
|
+
const file = attachments.getInitialFileValue(context.instanceNode);
|
|
141
|
+
const initialState = instanceAttachmentState(context, {
|
|
142
|
+
nodeId,
|
|
143
|
+
file,
|
|
144
|
+
writtenAt: null,
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
const [getState, setState] = createSignal<InstanceAttachmentState>(initialState);
|
|
148
|
+
|
|
149
|
+
const decodeInstanceValue: DecodeInstanceValue = (value) => {
|
|
150
|
+
const { computedName, intrinsicName } = getState();
|
|
151
|
+
|
|
152
|
+
if (value === '') {
|
|
153
|
+
if (computedName != null || intrinsicName != null) {
|
|
154
|
+
throw new ErrorProductionDesignPendingError(
|
|
155
|
+
`Unexpected file name reference. Expected one of "${computedName}", "${intrinsicName}", got: ""`
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (value === intrinsicName) {
|
|
161
|
+
return computedName ?? intrinsicName;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if (value === computedName) {
|
|
165
|
+
return computedName;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
throw new ErrorProductionDesignPendingError(
|
|
169
|
+
`Unexpected file name reference. Expected one of "${computedName}", "${intrinsicName}", got: "${value}"`
|
|
170
|
+
);
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
const getValue = createMemo(() => {
|
|
174
|
+
const { computedName, file: currentFile } = getState();
|
|
175
|
+
|
|
176
|
+
if (computedName == null) {
|
|
177
|
+
return currentFile;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
return new File([currentFile], computedName, {
|
|
181
|
+
type: currentFile.type,
|
|
182
|
+
});
|
|
183
|
+
});
|
|
184
|
+
const setValue: SimpleAtomicStateSetter<InstanceAttachmentRuntimeValue> = (value) => {
|
|
185
|
+
const updatedState = instanceAttachmentState(context, {
|
|
186
|
+
nodeId,
|
|
187
|
+
file: value,
|
|
188
|
+
writtenAt: new Date(),
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
return setState(updatedState).file;
|
|
192
|
+
};
|
|
193
|
+
const valueState = [getValue, setValue] as const;
|
|
194
|
+
|
|
195
|
+
const getFileName = createMemo(() => {
|
|
196
|
+
const { computedName, intrinsicName } = getState();
|
|
197
|
+
|
|
198
|
+
return computedName ?? intrinsicName;
|
|
199
|
+
});
|
|
200
|
+
const getInstanceValue = createMemo(() => getFileName() ?? '');
|
|
201
|
+
|
|
202
|
+
return InstanceAttachment.init(context, {
|
|
203
|
+
getFileName,
|
|
204
|
+
getInstanceValue,
|
|
205
|
+
decodeInstanceValue,
|
|
206
|
+
|
|
207
|
+
getValue,
|
|
208
|
+
setValue,
|
|
209
|
+
valueState,
|
|
210
|
+
});
|
|
211
|
+
});
|
|
212
|
+
};
|
|
@@ -1,57 +1,27 @@
|
|
|
1
1
|
import type { Signal } from 'solid-js';
|
|
2
2
|
import { createComputed, createMemo, createSignal, untrack } from 'solid-js';
|
|
3
|
-
import { ErrorProductionDesignPendingError } from '../../error/ErrorProductionDesignPendingError.ts';
|
|
4
3
|
import type { InstanceValueContext } from '../../instance/internal-api/InstanceValueContext.ts';
|
|
5
4
|
import type { BindComputationExpression } from '../../parse/expression/BindComputationExpression.ts';
|
|
6
5
|
import { createComputedExpression } from './createComputedExpression.ts';
|
|
7
6
|
import type { SimpleAtomicState, SimpleAtomicStateSetter } from './types.ts';
|
|
8
7
|
|
|
9
|
-
|
|
8
|
+
const isInstanceFirstLoad = (context: InstanceValueContext) => {
|
|
9
|
+
return context.rootDocument.initializationMode === 'create';
|
|
10
|
+
};
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
|
-
*
|
|
13
|
+
* Special case, does not correspond to any event.
|
|
14
|
+
*
|
|
15
|
+
* @see {@link shouldPreloadUID}
|
|
13
16
|
*/
|
|
14
|
-
const
|
|
15
|
-
return
|
|
17
|
+
const isEditInitialLoad = (context: InstanceValueContext) => {
|
|
18
|
+
return context.rootDocument.initializationMode === 'edit';
|
|
16
19
|
};
|
|
17
20
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
* Specifies the source of a {@link createInstanceValueState} signal's initial
|
|
21
|
-
* value state, where:
|
|
22
|
-
*
|
|
23
|
-
* - 'FORM_DEFAULT': Derives the initial state from the form's definition of
|
|
24
|
-
* the node itself. This is the default option, appropriate when
|
|
25
|
-
* initializing a form without additional primary instance data. In other
|
|
26
|
-
* words, this value should not be used for edits.
|
|
27
|
-
*
|
|
28
|
-
* - 'PRIMARY_INSTANCE': Derives the initial state from the current text
|
|
29
|
-
* content of the {@link ValueNode.contextNode}. This option should be
|
|
30
|
-
* specified when initializing a form with existing primary instance data,
|
|
31
|
-
* such as when editing a previous submission.
|
|
32
|
-
*
|
|
33
|
-
* @default 'FORM_DEFAULT'
|
|
34
|
-
*
|
|
35
|
-
* Specifies whether a {@link createInstanceValueState} signal's initial state
|
|
36
|
-
* should be derived from the current text content of the
|
|
37
|
-
* {@link ValueNode.contextNode | primary instance DOM state}.
|
|
38
|
-
*/
|
|
39
|
-
readonly initialValueSource?: InitialValueSource;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
const getInitialValue = (
|
|
43
|
-
context: InstanceValueContext,
|
|
44
|
-
options: InstanceValueStateOptions
|
|
45
|
-
): string => {
|
|
46
|
-
const { initialValueSource = 'FORM_DEFAULT' } = options;
|
|
47
|
-
|
|
48
|
-
if (initialValueSource === 'FORM_DEFAULT') {
|
|
49
|
-
const { defaultValue } = context.definition;
|
|
50
|
-
|
|
51
|
-
return context.decodeInstanceValue(defaultValue);
|
|
52
|
-
}
|
|
21
|
+
const getInitialValue = (context: InstanceValueContext): string => {
|
|
22
|
+
const sourceNode = context.instanceNode ?? context.definition.template;
|
|
53
23
|
|
|
54
|
-
|
|
24
|
+
return context.decodeInstanceValue(sourceNode.value);
|
|
55
25
|
};
|
|
56
26
|
|
|
57
27
|
type BaseValueState = Signal<string>;
|
|
@@ -118,6 +88,16 @@ const guardDownstreamReadonlyWrites = (
|
|
|
118
88
|
*/
|
|
119
89
|
const PRELOAD_UID_EXPRESSION = 'concat("uuid:", uuid())';
|
|
120
90
|
|
|
91
|
+
/**
|
|
92
|
+
* @todo It feels increasingly awkward to keep piling up preload stuff here, but it won't stay that way for long. In the meantime, this seems like the best way to express the cases where `preload="uid"` should be effective, i.e.:
|
|
93
|
+
*
|
|
94
|
+
* - When an instance is first loaded ({@link isInstanceFirstLoad})
|
|
95
|
+
* - When an instance is initially loaded for editing ({@link isEditInitialLoad})
|
|
96
|
+
*/
|
|
97
|
+
const shouldPreloadUID = (context: InstanceValueContext) => {
|
|
98
|
+
return isInstanceFirstLoad(context) || isEditInitialLoad(context);
|
|
99
|
+
};
|
|
100
|
+
|
|
121
101
|
/**
|
|
122
102
|
* @todo This is a temporary one-off, until we support the full range of
|
|
123
103
|
* {@link https://getodk.github.io/xforms-spec/#preload-attributes | preloads}.
|
|
@@ -129,12 +109,11 @@ const PRELOAD_UID_EXPRESSION = 'concat("uuid:", uuid())';
|
|
|
129
109
|
*/
|
|
130
110
|
const setPreloadUIDValue = (
|
|
131
111
|
context: InstanceValueContext,
|
|
132
|
-
valueState: RelevantValueState
|
|
133
|
-
options: InstanceValueStateOptions
|
|
112
|
+
valueState: RelevantValueState
|
|
134
113
|
): void => {
|
|
135
114
|
const { preload } = context.definition.bind;
|
|
136
115
|
|
|
137
|
-
if (preload?.type !== 'uid' || !
|
|
116
|
+
if (preload?.type !== 'uid' || !shouldPreloadUID(context)) {
|
|
138
117
|
return;
|
|
139
118
|
}
|
|
140
119
|
|
|
@@ -182,26 +161,23 @@ export type InstanceValueState = SimpleAtomicState<string>;
|
|
|
182
161
|
* Provides a consistent interface for value nodes of any type which:
|
|
183
162
|
*
|
|
184
163
|
* - derives initial state from either an existing instance (e.g. for edits) or
|
|
185
|
-
* the node's definition (e.g. initializing a new
|
|
164
|
+
* the node's definition (e.g. initializing a new instance)
|
|
186
165
|
* - decodes current primary instance state into the value node's runtime type
|
|
187
166
|
* - encodes updated runtime values to store updated instance state
|
|
188
167
|
* - initializes reactive computation of `calculate` bind expressions for those
|
|
189
168
|
* nodes defined with one
|
|
190
169
|
* - prevents downstream writes to nodes in a readonly state
|
|
191
170
|
*/
|
|
192
|
-
export const createInstanceValueState = (
|
|
193
|
-
context: InstanceValueContext,
|
|
194
|
-
options: InstanceValueStateOptions = {}
|
|
195
|
-
): InstanceValueState => {
|
|
171
|
+
export const createInstanceValueState = (context: InstanceValueContext): InstanceValueState => {
|
|
196
172
|
return context.scope.runTask(() => {
|
|
197
|
-
const initialValue = getInitialValue(context
|
|
173
|
+
const initialValue = getInitialValue(context);
|
|
198
174
|
const baseValueState = createSignal(initialValue);
|
|
199
175
|
const relevantValueState = createRelevantValueState(context, baseValueState);
|
|
200
176
|
|
|
201
177
|
/**
|
|
202
178
|
* @see {@link setPreloadUIDValue} for important details about spec ordering of events and computations.
|
|
203
179
|
*/
|
|
204
|
-
setPreloadUIDValue(context, relevantValueState
|
|
180
|
+
setPreloadUIDValue(context, relevantValueState);
|
|
205
181
|
|
|
206
182
|
const { calculate } = context.definition.bind;
|
|
207
183
|
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { FetchResourceResponse } from '../client/resources.ts';
|
|
2
|
+
|
|
3
|
+
const CONTENT_TYPE_CHARSET_PATTERN = /\s*;\s*charset\s*=.*$/;
|
|
4
|
+
|
|
5
|
+
const stripContentTypeCharset = (contentType: string): string => {
|
|
6
|
+
return contentType.replace(CONTENT_TYPE_CHARSET_PATTERN, '');
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export const getResponseContentType = (response: FetchResourceResponse): string | null => {
|
|
10
|
+
const { headers } = response;
|
|
11
|
+
|
|
12
|
+
if (headers == null) {
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const contentType = headers.get('content-type');
|
|
17
|
+
|
|
18
|
+
if (contentType != null) {
|
|
19
|
+
return stripContentTypeCharset(contentType);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (headers instanceof Headers) {
|
|
23
|
+
return contentType;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
for (const [header, value] of headers) {
|
|
27
|
+
if (header.toLowerCase() === 'content-type') {
|
|
28
|
+
return stripContentTypeCharset(value);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return null;
|
|
33
|
+
};
|
package/src/parse/XFormDOM.ts
CHANGED
|
@@ -104,9 +104,7 @@ const normalizeDefaultMetaBindings = (
|
|
|
104
104
|
let meta = getMetaElement(primaryInstanceRoot);
|
|
105
105
|
let instanceID = getMetaChildElement(meta, 'instanceID');
|
|
106
106
|
|
|
107
|
-
|
|
108
|
-
meta = createNamespacedChildElement(primaryInstanceRoot, OPENROSA_XFORMS_NAMESPACE_URI, 'meta');
|
|
109
|
-
}
|
|
107
|
+
meta ??= createNamespacedChildElement(primaryInstanceRoot, OPENROSA_XFORMS_NAMESPACE_URI, 'meta');
|
|
110
108
|
|
|
111
109
|
if (instanceID == null) {
|
|
112
110
|
instanceID = createNamespacedChildElement(meta, meta.namespaceURI, 'instanceID');
|
|
@@ -207,6 +207,10 @@ export class BodyDefinition extends DependencyContext implements BodyElementPare
|
|
|
207
207
|
return this.elementsByReference.get(reference) ?? null;
|
|
208
208
|
}
|
|
209
209
|
|
|
210
|
+
getBodyElementType(reference: BodyElementReference): AnyBodyElementType | null {
|
|
211
|
+
return this.elementsByReference.getBodyElementType(reference);
|
|
212
|
+
}
|
|
213
|
+
|
|
210
214
|
getChildElementDefinitions(
|
|
211
215
|
form: XFormDefinition,
|
|
212
216
|
parent: BodyElementParentContext,
|