@cratis/scene.components 3.5.0 → 3.6.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.
Files changed (83) hide show
  1. package/README.md +39 -4
  2. package/bindings/bindingRegistry.ts +52 -4
  3. package/bindings/for_bindingRegistry/when_registering_query_identities.ts +81 -0
  4. package/bindings/for_requireArcProxy/when_mounting_bound_adapters.tsx +4 -2
  5. package/cratisComponents.ts +2 -0
  6. package/cratisComponentsPackage.ts +2 -1
  7. package/data/SingleResultRuntime.tsx +17 -3
  8. package/data/for_SceneDataTable/when_forwarding_query_arguments.tsx +19 -0
  9. package/dist/cjs/bindings/bindingRegistry.js +52 -4
  10. package/dist/cjs/bindings/bindingRegistry.js.map +1 -1
  11. package/dist/cjs/cratisComponents.js +2 -0
  12. package/dist/cjs/cratisComponents.js.map +1 -1
  13. package/dist/cjs/cratisComponentsPackage.js +2 -1
  14. package/dist/cjs/cratisComponentsPackage.js.map +1 -1
  15. package/dist/cjs/data/SingleResultRuntime.js +16 -1
  16. package/dist/cjs/data/SingleResultRuntime.js.map +1 -1
  17. package/dist/cjs/forms/SceneQueryInputForm.js +141 -0
  18. package/dist/cjs/forms/SceneQueryInputForm.js.map +1 -0
  19. package/dist/cjs/forms/queryInputs.js +50 -0
  20. package/dist/cjs/forms/queryInputs.js.map +1 -0
  21. package/dist/cjs/index.js +6 -0
  22. package/dist/cjs/index.js.map +1 -1
  23. package/dist/esm/bindings/bindingRegistry.d.ts +4 -0
  24. package/dist/esm/bindings/bindingRegistry.d.ts.map +1 -1
  25. package/dist/esm/bindings/bindingRegistry.js +49 -5
  26. package/dist/esm/bindings/bindingRegistry.js.map +1 -1
  27. package/dist/esm/bindings/for_bindingRegistry/when_registering_query_identities.d.ts +2 -0
  28. package/dist/esm/bindings/for_bindingRegistry/when_registering_query_identities.d.ts.map +1 -0
  29. package/dist/esm/bindings/for_bindingRegistry/when_registering_query_identities.js +73 -0
  30. package/dist/esm/bindings/for_bindingRegistry/when_registering_query_identities.js.map +1 -0
  31. package/dist/esm/bindings/for_requireArcProxy/when_mounting_bound_adapters.js +2 -2
  32. package/dist/esm/bindings/for_requireArcProxy/when_mounting_bound_adapters.js.map +1 -1
  33. package/dist/esm/cratisComponents.d.ts.map +1 -1
  34. package/dist/esm/cratisComponents.js +2 -0
  35. package/dist/esm/cratisComponents.js.map +1 -1
  36. package/dist/esm/cratisComponentsPackage.d.ts.map +1 -1
  37. package/dist/esm/cratisComponentsPackage.js +2 -1
  38. package/dist/esm/cratisComponentsPackage.js.map +1 -1
  39. package/dist/esm/data/SingleResultRuntime.d.ts +2 -1
  40. package/dist/esm/data/SingleResultRuntime.d.ts.map +1 -1
  41. package/dist/esm/data/SingleResultRuntime.js +16 -1
  42. package/dist/esm/data/SingleResultRuntime.js.map +1 -1
  43. package/dist/esm/data/for_SceneDataTable/when_forwarding_query_arguments.js +17 -0
  44. package/dist/esm/data/for_SceneDataTable/when_forwarding_query_arguments.js.map +1 -1
  45. package/dist/esm/for_cratisComponentsPackage/when_describing_query_input_form.d.ts +2 -0
  46. package/dist/esm/for_cratisComponentsPackage/when_describing_query_input_form.d.ts.map +1 -0
  47. package/dist/esm/for_cratisComponentsPackage/when_describing_query_input_form.js +14 -0
  48. package/dist/esm/for_cratisComponentsPackage/when_describing_query_input_form.js.map +1 -0
  49. package/dist/esm/forms/SceneQueryInputForm.d.ts +3 -0
  50. package/dist/esm/forms/SceneQueryInputForm.d.ts.map +1 -0
  51. package/dist/esm/forms/SceneQueryInputForm.js +139 -0
  52. package/dist/esm/forms/SceneQueryInputForm.js.map +1 -0
  53. package/dist/esm/forms/for_SceneQueryInputForm/ProjectLookup.d.ts +26 -0
  54. package/dist/esm/forms/for_SceneQueryInputForm/ProjectLookup.d.ts.map +1 -0
  55. package/dist/esm/forms/for_SceneQueryInputForm/ProjectLookup.js +44 -0
  56. package/dist/esm/forms/for_SceneQueryInputForm/ProjectLookup.js.map +1 -0
  57. package/dist/esm/forms/for_SceneQueryInputForm/when_submitting_generated_guid_parameters.d.ts +2 -0
  58. package/dist/esm/forms/for_SceneQueryInputForm/when_submitting_generated_guid_parameters.d.ts.map +1 -0
  59. package/dist/esm/forms/for_SceneQueryInputForm/when_submitting_generated_guid_parameters.js +175 -0
  60. package/dist/esm/forms/for_SceneQueryInputForm/when_submitting_generated_guid_parameters.js.map +1 -0
  61. package/dist/esm/forms/for_SceneQueryInputForm/when_submitting_native_queries.d.ts +2 -0
  62. package/dist/esm/forms/for_SceneQueryInputForm/when_submitting_native_queries.d.ts.map +1 -0
  63. package/dist/esm/forms/for_SceneQueryInputForm/when_submitting_native_queries.js +413 -0
  64. package/dist/esm/forms/for_SceneQueryInputForm/when_submitting_native_queries.js.map +1 -0
  65. package/dist/esm/forms/index.d.ts +2 -0
  66. package/dist/esm/forms/index.d.ts.map +1 -1
  67. package/dist/esm/forms/index.js +1 -0
  68. package/dist/esm/forms/index.js.map +1 -1
  69. package/dist/esm/forms/queryInputs.d.ts +10 -0
  70. package/dist/esm/forms/queryInputs.d.ts.map +1 -0
  71. package/dist/esm/forms/queryInputs.js +47 -0
  72. package/dist/esm/forms/queryInputs.js.map +1 -0
  73. package/dist/esm/index.js +2 -1
  74. package/dist/esm/index.js.map +1 -1
  75. package/dist/esm/tsconfig.tsbuildinfo +1 -1
  76. package/for_cratisComponentsPackage/when_describing_query_input_form.ts +17 -0
  77. package/forms/SceneQueryInputForm.tsx +79 -0
  78. package/forms/for_SceneQueryInputForm/ProjectLookup.ts +54 -0
  79. package/forms/for_SceneQueryInputForm/when_submitting_generated_guid_parameters.tsx +188 -0
  80. package/forms/for_SceneQueryInputForm/when_submitting_native_queries.tsx +423 -0
  81. package/forms/index.ts +2 -0
  82. package/forms/queryInputs.ts +50 -0
  83. package/package.json +11 -7
@@ -1 +1 @@
1
- {"version":3,"file":"cratisComponentsPackage.js","sources":["../../cratisComponentsPackage.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { PackageKind, ScenePackage } from '@cratis/scene.model';\nimport { ScenePackageBundle } from '@cratis/scene.react';\nimport { cratisComponents, cratisComponentsPackageName } from './cratisComponents';\n\n/**\n * The `Cratis.Components` package's declaration - what a profile gets when it lists this package.\n *\n * This is the concrete case the whole package-dependency mechanism exists for. `@cratis/components` is\n * not a self-contained library: every component in it is a wrapper over a PrimeReact widget, and its own\n * styling is a `--cratis-*` token layer (`@cratis/components/tokens`) plus the component stylesheets and\n * compiled Tailwind utilities in `@cratis/components/styles`. Activate it in a profile without PrimeReact\n * and nothing renders; activate it without Tailwind and everything renders unstyled. Both are stated as\n * dependencies so a package picker can say so while the profile is being configured, instead of leaving\n * it to be discovered when the page opens.\n *\n * The version ranges are the real ones the library carries. `>=11.0.0` for PrimeReact: version 3.0.0\n * declares `primereact@^11` as a peer dependency and is built against version 11's component set, so the\n * span across the major boundary that the previous `>=10.9.0` range described is over. The `--cratis-*`\n * tokens still resolve a version 10 theme variable as their last fallback, but that is an upgrade-window\n * courtesy for an application with a compiled version 10 stylesheet still on the page - not a version of\n * PrimeReact this package can be activated against. `^4.0.0` for Tailwind, because the utility sheet is\n * compiled against Tailwind 4.\n */\nexport const cratisComponentsPackageManifest: ScenePackage = {\n name: cratisComponentsPackageName,\n version: '3.0.0',\n kind: PackageKind.ComponentLibrary,\n dependencies: [\n { name: 'PrimeReact', versionRange: '>=11.0.0' },\n { name: 'Tailwind', versionRange: '^4.0.0' },\n ],\n components: [\n 'page',\n 'dataPage',\n 'formElement',\n 'singleResult',\n 'dataTable',\n 'table',\n 'observableDataTable',\n 'commandForm',\n 'inputTextField',\n 'numberField',\n 'checkboxField',\n 'textAreaField',\n 'dropdownField',\n 'sliderField',\n 'calendarField',\n 'colorPickerField',\n 'multiSelectField',\n 'chipsField',\n 'radioButtonField',\n 'radioGroupField',\n 'dialog',\n 'confirmationDialog',\n 'busyIndicatorDialog',\n 'commandDialog',\n 'stepperCommandDialog',\n 'icon',\n 'tooltip',\n 'dropdown',\n 'errorBoundary',\n 'objectContentEditor',\n 'objectNavigationalBar',\n 'schemaEditor',\n 'timeMachine',\n 'filterPanel',\n 'toolbar',\n 'toolbarButton',\n 'toolbarGroup',\n 'toolbarSeparator',\n ],\n\n // A component library ships components, and nothing else. Layouts, screen templates and dialog\n // templates all belong to a Blueprint: they are decisions about what an application looks like as a\n // whole, and this package deliberately makes none of them - it provides the Arc-bound composites a\n // template is *built from*, so that a blueprint can place a `dataPage` in a slot and configure it,\n // rather than shipping one opinionated data page nobody can rearrange.\n layouts: [],\n screenTemplates: [],\n dialogTemplates: [],\n\n // No themes either, for a different reason: `@cratis/components` has no palette of its own. It reads\n // a `--cratis-*` variable layer that resolves whatever is in front of it - the `--p-*` properties a\n // PrimeReact 11 preset emits at runtime, or a Scene theme through this package's token bridge.\n // Shipping a theme here would be this library asserting a look it was specifically built not to have.\n themes: [],\n\n displayName: 'Cratis Components',\n description: \"Cratis' Arc-bound data, form and dialog composites, built on PrimeReact and Tailwind. dataTable and table accept optional object-valued queryArguments for collection queries. singleResult displays one read-only scalar own resultField of an optional model using an explicit query, object queryArguments and enabled: true.\",\n module: '@cratis/scene.components',\n license: 'MIT',\n licenseUrl: 'https://github.com/Cratis/Scene/blob/main/LICENSE',\n};\n\n/**\n * The `Cratis.Components` package as a loadable bundle - the manifest above, plus the React components\n * behind the names it declares.\n *\n * No `layouts`, `screenTemplates`, `dialogTemplates` or `themes` are provided, matching a manifest that\n * declares none of them; `validatePackageBundle` is what proves the two halves agree.\n */\nexport const cratisComponentsPackage: ScenePackageBundle = {\n manifest: cratisComponentsPackageManifest,\n components: cratisComponents,\n};\n"],"names":["cratisComponentsPackageManifest","name","cratisComponentsPackageName","version","kind","PackageKind","ComponentLibrary","dependencies","versionRange","components","layouts","screenTemplates","dialogTemplates","themes","displayName","description","module","license","licenseUrl","cratisComponentsPackage","manifest","cratisComponents"],"mappings":";;;;;AAAA;AACA;AAMA;;;;;;;;;;;;;;;;;;UAmBaA,+BAAAA,GAAgD;IACzDC,IAAAA,EAAMC,4CAAAA;IACNC,OAAAA,EAAS,OAAA;AACTC,IAAAA,IAAAA,EAAMC,wBAAYC,gBAAgB;IAClCC,YAAAA,EAAc;AACV,QAAA;YAAEN,IAAAA,EAAM,YAAA;YAAcO,YAAAA,EAAc;AAAW,SAAA;AAC/C,QAAA;YAAEP,IAAAA,EAAM,UAAA;YAAYO,YAAAA,EAAc;AAAS;AAC9C,KAAA;IACDC,UAAAA,EAAY;AACR,QAAA,MAAA;AACA,QAAA,UAAA;AACA,QAAA,aAAA;AACA,QAAA,cAAA;AACA,QAAA,WAAA;AACA,QAAA,OAAA;AACA,QAAA,qBAAA;AACA,QAAA,aAAA;AACA,QAAA,gBAAA;AACA,QAAA,aAAA;AACA,QAAA,eAAA;AACA,QAAA,eAAA;AACA,QAAA,eAAA;AACA,QAAA,aAAA;AACA,QAAA,eAAA;AACA,QAAA,kBAAA;AACA,QAAA,kBAAA;AACA,QAAA,YAAA;AACA,QAAA,kBAAA;AACA,QAAA,iBAAA;AACA,QAAA,QAAA;AACA,QAAA,oBAAA;AACA,QAAA,qBAAA;AACA,QAAA,eAAA;AACA,QAAA,sBAAA;AACA,QAAA,MAAA;AACA,QAAA,SAAA;AACA,QAAA,UAAA;AACA,QAAA,eAAA;AACA,QAAA,qBAAA;AACA,QAAA,uBAAA;AACA,QAAA,cAAA;AACA,QAAA,aAAA;AACA,QAAA,aAAA;AACA,QAAA,SAAA;AACA,QAAA,eAAA;AACA,QAAA,cAAA;AACA,QAAA;AACH,KAAA;;;;;;AAODC,IAAAA,OAAAA,EAAS,EAAE;AACXC,IAAAA,eAAAA,EAAiB,EAAE;AACnBC,IAAAA,eAAAA,EAAiB,EAAE;;;;;AAMnBC,IAAAA,MAAAA,EAAQ,EAAE;IAEVC,WAAAA,EAAa,mBAAA;IACbC,WAAAA,EAAa,kUAAA;IACbC,MAAAA,EAAQ,0BAAA;IACRC,OAAAA,EAAS,KAAA;IACTC,UAAAA,EAAY;AAChB;AAEA;;;;;;UAOaC,uBAAAA,GAA8C;IACvDC,QAAAA,EAAUpB,+BAAAA;IACVS,UAAAA,EAAYY;AAChB;;;"}
1
+ {"version":3,"file":"cratisComponentsPackage.js","sources":["../../cratisComponentsPackage.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { PackageKind, ScenePackage } from '@cratis/scene.model';\nimport { ScenePackageBundle } from '@cratis/scene.react';\nimport { cratisComponents, cratisComponentsPackageName } from './cratisComponents';\n\n/**\n * The `Cratis.Components` package's declaration - what a profile gets when it lists this package.\n *\n * This is the concrete case the whole package-dependency mechanism exists for. `@cratis/components` is\n * not a self-contained library: every component in it is a wrapper over a PrimeReact widget, and its own\n * styling is a `--cratis-*` token layer (`@cratis/components/tokens`) plus the component stylesheets and\n * compiled Tailwind utilities in `@cratis/components/styles`. Activate it in a profile without PrimeReact\n * and nothing renders; activate it without Tailwind and everything renders unstyled. Both are stated as\n * dependencies so a package picker can say so while the profile is being configured, instead of leaving\n * it to be discovered when the page opens.\n *\n * The version ranges are the real ones the library carries. `>=11.0.0` for PrimeReact: version 3.0.0\n * declares `primereact@^11` as a peer dependency and is built against version 11's component set, so the\n * span across the major boundary that the previous `>=10.9.0` range described is over. The `--cratis-*`\n * tokens still resolve a version 10 theme variable as their last fallback, but that is an upgrade-window\n * courtesy for an application with a compiled version 10 stylesheet still on the page - not a version of\n * PrimeReact this package can be activated against. `^4.0.0` for Tailwind, because the utility sheet is\n * compiled against Tailwind 4.\n */\nexport const cratisComponentsPackageManifest: ScenePackage = {\n name: cratisComponentsPackageName,\n version: '3.0.0',\n kind: PackageKind.ComponentLibrary,\n dependencies: [\n { name: 'PrimeReact', versionRange: '>=11.0.0' },\n { name: 'Tailwind', versionRange: '^4.0.0' },\n ],\n components: [\n 'page',\n 'dataPage',\n 'formElement',\n 'singleResult',\n 'queryInputForm',\n 'dataTable',\n 'table',\n 'observableDataTable',\n 'commandForm',\n 'inputTextField',\n 'numberField',\n 'checkboxField',\n 'textAreaField',\n 'dropdownField',\n 'sliderField',\n 'calendarField',\n 'colorPickerField',\n 'multiSelectField',\n 'chipsField',\n 'radioButtonField',\n 'radioGroupField',\n 'dialog',\n 'confirmationDialog',\n 'busyIndicatorDialog',\n 'commandDialog',\n 'stepperCommandDialog',\n 'icon',\n 'tooltip',\n 'dropdown',\n 'errorBoundary',\n 'objectContentEditor',\n 'objectNavigationalBar',\n 'schemaEditor',\n 'timeMachine',\n 'filterPanel',\n 'toolbar',\n 'toolbarButton',\n 'toolbarGroup',\n 'toolbarSeparator',\n ],\n\n // A component library ships components, and nothing else. Layouts, screen templates and dialog\n // templates all belong to a Blueprint: they are decisions about what an application looks like as a\n // whole, and this package deliberately makes none of them - it provides the Arc-bound composites a\n // template is *built from*, so that a blueprint can place a `dataPage` in a slot and configure it,\n // rather than shipping one opinionated data page nobody can rearrange.\n layouts: [],\n screenTemplates: [],\n dialogTemplates: [],\n\n // No themes either, for a different reason: `@cratis/components` has no palette of its own. It reads\n // a `--cratis-*` variable layer that resolves whatever is in front of it - the `--p-*` properties a\n // PrimeReact 11 preset emits at runtime, or a Scene theme through this package's token bridge.\n // Shipping a theme here would be this library asserting a look it was specifically built not to have.\n themes: [],\n\n displayName: 'Cratis Components',\n description: \"Cratis' Arc-bound data, form and dialog composites, built on PrimeReact and Tailwind. dataTable and table accept optional object-valued queryArguments for collection queries. singleResult displays one read-only scalar own resultField of an optional model using an explicit query, object queryArguments and enabled: true. queryInputForm commits explicit string inputs on submit to the same optional-single runtime; drafts never execute a query.\",\n module: '@cratis/scene.components',\n license: 'MIT',\n licenseUrl: 'https://github.com/Cratis/Scene/blob/main/LICENSE',\n};\n\n/**\n * The `Cratis.Components` package as a loadable bundle - the manifest above, plus the React components\n * behind the names it declares.\n *\n * No `layouts`, `screenTemplates`, `dialogTemplates` or `themes` are provided, matching a manifest that\n * declares none of them; `validatePackageBundle` is what proves the two halves agree.\n */\nexport const cratisComponentsPackage: ScenePackageBundle = {\n manifest: cratisComponentsPackageManifest,\n components: cratisComponents,\n};\n"],"names":["cratisComponentsPackageManifest","name","cratisComponentsPackageName","version","kind","PackageKind","ComponentLibrary","dependencies","versionRange","components","layouts","screenTemplates","dialogTemplates","themes","displayName","description","module","license","licenseUrl","cratisComponentsPackage","manifest","cratisComponents"],"mappings":";;;;;AAAA;AACA;AAMA;;;;;;;;;;;;;;;;;;UAmBaA,+BAAAA,GAAgD;IACzDC,IAAAA,EAAMC,4CAAAA;IACNC,OAAAA,EAAS,OAAA;AACTC,IAAAA,IAAAA,EAAMC,wBAAYC,gBAAgB;IAClCC,YAAAA,EAAc;AACV,QAAA;YAAEN,IAAAA,EAAM,YAAA;YAAcO,YAAAA,EAAc;AAAW,SAAA;AAC/C,QAAA;YAAEP,IAAAA,EAAM,UAAA;YAAYO,YAAAA,EAAc;AAAS;AAC9C,KAAA;IACDC,UAAAA,EAAY;AACR,QAAA,MAAA;AACA,QAAA,UAAA;AACA,QAAA,aAAA;AACA,QAAA,cAAA;AACA,QAAA,gBAAA;AACA,QAAA,WAAA;AACA,QAAA,OAAA;AACA,QAAA,qBAAA;AACA,QAAA,aAAA;AACA,QAAA,gBAAA;AACA,QAAA,aAAA;AACA,QAAA,eAAA;AACA,QAAA,eAAA;AACA,QAAA,eAAA;AACA,QAAA,aAAA;AACA,QAAA,eAAA;AACA,QAAA,kBAAA;AACA,QAAA,kBAAA;AACA,QAAA,YAAA;AACA,QAAA,kBAAA;AACA,QAAA,iBAAA;AACA,QAAA,QAAA;AACA,QAAA,oBAAA;AACA,QAAA,qBAAA;AACA,QAAA,eAAA;AACA,QAAA,sBAAA;AACA,QAAA,MAAA;AACA,QAAA,SAAA;AACA,QAAA,UAAA;AACA,QAAA,eAAA;AACA,QAAA,qBAAA;AACA,QAAA,uBAAA;AACA,QAAA,cAAA;AACA,QAAA,aAAA;AACA,QAAA,aAAA;AACA,QAAA,SAAA;AACA,QAAA,eAAA;AACA,QAAA,cAAA;AACA,QAAA;AACH,KAAA;;;;;;AAODC,IAAAA,OAAAA,EAAS,EAAE;AACXC,IAAAA,eAAAA,EAAiB,EAAE;AACnBC,IAAAA,eAAAA,EAAiB,EAAE;;;;;AAMnBC,IAAAA,MAAAA,EAAQ,EAAE;IAEVC,WAAAA,EAAa,mBAAA;IACbC,WAAAA,EAAa,6bAAA;IACbC,MAAAA,EAAQ,0BAAA;IACRC,OAAAA,EAAS,KAAA;IACTC,UAAAA,EAAY;AAChB;AAEA;;;;;;UAOaC,uBAAAA,GAA8C;IACvDC,QAAAA,EAAUpB,+BAAAA;IACVS,UAAAA,EAAYY;AAChB;;;"}
@@ -5,12 +5,13 @@ Object.defineProperty(exports, '__esModule', { value: true });
5
5
  var jsxRuntime = require('react/jsx-runtime');
6
6
  var react = require('react');
7
7
  var arc_react = require('@cratis/arc.react');
8
+ var fundamentals = require('@cratis/fundamentals');
8
9
  var SingleResultStatus = require('./SingleResultStatus.js');
9
10
 
10
11
  /**
11
12
  * Private execution owner. Arc owns validation, routing, HTTP and deserialization; this component
12
13
  * owns only request lifetime and presentation. No shared cache can hand B the result belonging to A.
13
- */ function SingleResultRuntime({ query, queryArguments, resultField }) {
14
+ */ function SingleResultRuntime({ query, queryArguments, resultField, stringInputs = false }) {
14
15
  const arc = react.useContext(arc_react.ArcContext);
15
16
  const { microservice, apiBasePath, origin, httpHeadersCallback, queryVersion } = arc;
16
17
  // Identity is deliberate: hosts replace immutable committed arguments rather than mutating them.
@@ -18,6 +19,7 @@ var SingleResultStatus = require('./SingleResultStatus.js');
18
19
  query,
19
20
  queryArguments,
20
21
  resultField,
22
+ stringInputs,
21
23
  microservice,
22
24
  apiBasePath,
23
25
  origin,
@@ -27,6 +29,7 @@ var SingleResultStatus = require('./SingleResultStatus.js');
27
29
  query,
28
30
  queryArguments,
29
31
  resultField,
32
+ stringInputs,
30
33
  microservice,
31
34
  apiBasePath,
32
35
  origin,
@@ -54,6 +57,18 @@ var SingleResultStatus = require('./SingleResultStatus.js');
54
57
  });
55
58
  return;
56
59
  }
60
+ // Arc perform does not validate argument-to-descriptor types. The form supports only
61
+ // scalar String/Guid inputs, matched by exact name and constructor, never by naming
62
+ // convention. This check is lazy and form-only; singleResult's host contract is intact.
63
+ if (request.stringInputs && !Object.entries(request.queryArguments).every(([name, value])=>{
64
+ const descriptors = instance.parameterDescriptors.filter((descriptor)=>descriptor.name === name);
65
+ return typeof value === 'string' && descriptors.length === 1 && !descriptors[0].isEnumerable && (descriptors[0].type === String || descriptors[0].type === fundamentals.Guid);
66
+ })) {
67
+ publish({
68
+ state: 'failure'
69
+ });
70
+ return;
71
+ }
57
72
  instance.setMicroservice(request.microservice);
58
73
  instance.setApiBasePath(request.apiBasePath ?? '');
59
74
  instance.setOrigin(request.origin ?? '');
@@ -1 +1 @@
1
- {"version":3,"file":"SingleResultRuntime.js","sources":["../../../data/SingleResultRuntime.tsx"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { useContext, useEffect, useMemo, useState } from 'react';\nimport { ArcContext } from '@cratis/arc.react';\nimport type { QueryFor } from '@cratis/arc/queries';\nimport type { BoundConstructor } from '../bindings/BoundConstructor';\nimport { SingleResultStatus } from './SingleResultStatus';\n\ninterface Props {\n query: BoundConstructor;\n queryArguments: Record<string, unknown>;\n resultField: string;\n}\n\ntype Outcome = { state: 'failure' | 'notFound' } | { state: 'success'; value: string };\n\n/**\n * Private execution owner. Arc owns validation, routing, HTTP and deserialization; this component\n * owns only request lifetime and presentation. No shared cache can hand B the result belonging to A.\n */\nexport default function SingleResultRuntime({ query, queryArguments, resultField }: Props) {\n const arc = useContext(ArcContext);\n const { microservice, apiBasePath, origin, httpHeadersCallback, queryVersion } = arc;\n // Identity is deliberate: hosts replace immutable committed arguments rather than mutating them.\n const request = useMemo(() => ({ query, queryArguments, resultField, microservice, apiBasePath, origin, httpHeadersCallback, queryVersion }),\n [query, queryArguments, resultField, microservice, apiBasePath, origin, httpHeadersCallback, queryVersion]);\n const [settled, setSettled] = useState<{ request: typeof request; outcome: Outcome }>();\n\n useEffect(() => {\n // Each effect setup is a generation, including StrictMode's setup/cleanup/setup replay.\n let current = true;\n let instance: QueryFor<unknown, Record<string, unknown>> | undefined;\n const publish = (outcome: Outcome) => {\n if (current) setSettled({ request, outcome });\n };\n const execute = async () => {\n try {\n // The registry intentionally stores constructors without an eager Arc dependency.\n instance = new request.query() as QueryFor<unknown, Record<string, unknown>>;\n if (instance.enumerable !== false) {\n publish({ state: 'failure' });\n return;\n }\n instance.setMicroservice(request.microservice);\n instance.setApiBasePath(request.apiBasePath ?? '');\n instance.setOrigin(request.origin ?? '');\n instance.setHttpHeadersCallback(request.httpHeadersCallback ?? (() => ({})));\n // Native perform validates required arguments and proxy rules before HTTP. No copying,\n // defaults, business validation, route construction or array wrapping happens here.\n const result = await instance.perform(request.queryArguments);\n if (!current) return;\n if (result.isSuccess !== true || result.isAuthorized !== true || result.isValid !== true || result.hasExceptions !== false || result.isReady === false) {\n publish({ state: 'failure' });\n return;\n }\n if (result.data === null || result.data === undefined) {\n publish({ state: 'notFound' });\n return;\n }\n if (typeof result.data !== 'object' || Array.isArray(result.data)) {\n publish({ state: 'failure' });\n return;\n }\n // Only one own data field, never a path, inherited member, getter or expression.\n const descriptor = Object.getOwnPropertyDescriptor(result.data, request.resultField);\n const value: unknown = descriptor && 'value' in descriptor ? descriptor.value : undefined;\n if (typeof value === 'string' || typeof value === 'boolean' || (typeof value === 'number' && Number.isFinite(value))) {\n publish({ state: 'success', value: String(value) });\n } else {\n publish({ state: 'failure' });\n }\n } catch {\n // Includes native AbortError rejections. Disposed generations cannot publish or leak\n // an unhandled promise, even when the HTTP boundary ignores cancellation.\n publish({ state: 'failure' });\n }\n };\n void execute();\n return () => {\n current = false;\n instance?.abortController?.abort();\n };\n }, [request]);\n\n // Mask old data during the render that changes inputs, before effect cleanup/setup runs.\n if (settled?.request !== request) return <SingleResultStatus state='loading' />;\n return <SingleResultStatus {...settled.outcome} />;\n}\n"],"names":["SingleResultRuntime","query","queryArguments","resultField","arc","useContext","ArcContext","microservice","apiBasePath","origin","httpHeadersCallback","queryVersion","request","useMemo","settled","setSettled","useState","useEffect","current","instance","publish","outcome","execute","enumerable","state","setMicroservice","setApiBasePath","setOrigin","setHttpHeadersCallback","result","perform","isSuccess","isAuthorized","isValid","hasExceptions","isReady","data","undefined","Array","isArray","descriptor","Object","getOwnPropertyDescriptor","value","Number","isFinite","String","abortController","abort","_jsx","SingleResultStatus"],"mappings":"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"}
1
+ {"version":3,"file":"SingleResultRuntime.js","sources":["../../../data/SingleResultRuntime.tsx"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { useContext, useEffect, useMemo, useState } from 'react';\nimport { ArcContext } from '@cratis/arc.react';\nimport type { QueryFor } from '@cratis/arc/queries';\nimport { Guid } from '@cratis/fundamentals';\nimport type { BoundConstructor } from '../bindings/BoundConstructor';\nimport { SingleResultStatus } from './SingleResultStatus';\n\ninterface Props {\n query: BoundConstructor;\n queryArguments: Record<string, unknown>;\n resultField: string;\n /** queryInputForm alone opts into scalar String/Guid descriptor mapping; no value conversion. */\n stringInputs?: boolean;\n}\n\ntype Outcome = { state: 'failure' | 'notFound' } | { state: 'success'; value: string };\n\n/**\n * Private execution owner. Arc owns validation, routing, HTTP and deserialization; this component\n * owns only request lifetime and presentation. No shared cache can hand B the result belonging to A.\n */\nexport default function SingleResultRuntime({ query, queryArguments, resultField, stringInputs = false }: Props) {\n const arc = useContext(ArcContext);\n const { microservice, apiBasePath, origin, httpHeadersCallback, queryVersion } = arc;\n // Identity is deliberate: hosts replace immutable committed arguments rather than mutating them.\n const request = useMemo(() => ({ query, queryArguments, resultField, stringInputs, microservice, apiBasePath, origin, httpHeadersCallback, queryVersion }),\n [query, queryArguments, resultField, stringInputs, microservice, apiBasePath, origin, httpHeadersCallback, queryVersion]);\n const [settled, setSettled] = useState<{ request: typeof request; outcome: Outcome }>();\n\n useEffect(() => {\n // Each effect setup is a generation, including StrictMode's setup/cleanup/setup replay.\n let current = true;\n let instance: QueryFor<unknown, Record<string, unknown>> | undefined;\n const publish = (outcome: Outcome) => {\n if (current) setSettled({ request, outcome });\n };\n const execute = async () => {\n try {\n // The registry intentionally stores constructors without an eager Arc dependency.\n instance = new request.query() as QueryFor<unknown, Record<string, unknown>>;\n if (instance.enumerable !== false) {\n publish({ state: 'failure' });\n return;\n }\n // Arc perform does not validate argument-to-descriptor types. The form supports only\n // scalar String/Guid inputs, matched by exact name and constructor, never by naming\n // convention. This check is lazy and form-only; singleResult's host contract is intact.\n if (request.stringInputs && !Object.entries(request.queryArguments).every(([name, value]) => {\n const descriptors = instance!.parameterDescriptors.filter(descriptor => descriptor.name === name);\n return typeof value === 'string' && descriptors.length === 1 && !descriptors[0].isEnumerable\n && (descriptors[0].type === String || descriptors[0].type === Guid);\n })) {\n publish({ state: 'failure' });\n return;\n }\n instance.setMicroservice(request.microservice);\n instance.setApiBasePath(request.apiBasePath ?? '');\n instance.setOrigin(request.origin ?? '');\n instance.setHttpHeadersCallback(request.httpHeadersCallback ?? (() => ({})));\n // Native perform validates required arguments and proxy rules before HTTP. No copying,\n // defaults, business validation, route construction or array wrapping happens here.\n const result = await instance.perform(request.queryArguments);\n if (!current) return;\n if (result.isSuccess !== true || result.isAuthorized !== true || result.isValid !== true || result.hasExceptions !== false || result.isReady === false) {\n publish({ state: 'failure' });\n return;\n }\n if (result.data === null || result.data === undefined) {\n publish({ state: 'notFound' });\n return;\n }\n if (typeof result.data !== 'object' || Array.isArray(result.data)) {\n publish({ state: 'failure' });\n return;\n }\n // Only one own data field, never a path, inherited member, getter or expression.\n const descriptor = Object.getOwnPropertyDescriptor(result.data, request.resultField);\n const value: unknown = descriptor && 'value' in descriptor ? descriptor.value : undefined;\n if (typeof value === 'string' || typeof value === 'boolean' || (typeof value === 'number' && Number.isFinite(value))) {\n publish({ state: 'success', value: String(value) });\n } else {\n publish({ state: 'failure' });\n }\n } catch {\n // Includes native AbortError rejections. Disposed generations cannot publish or leak\n // an unhandled promise, even when the HTTP boundary ignores cancellation.\n publish({ state: 'failure' });\n }\n };\n void execute();\n return () => {\n current = false;\n instance?.abortController?.abort();\n };\n }, [request]);\n\n // Mask old data during the render that changes inputs, before effect cleanup/setup runs.\n if (settled?.request !== request) return <SingleResultStatus state='loading' />;\n return <SingleResultStatus {...settled.outcome} />;\n}\n"],"names":["SingleResultRuntime","query","queryArguments","resultField","stringInputs","arc","useContext","ArcContext","microservice","apiBasePath","origin","httpHeadersCallback","queryVersion","request","useMemo","settled","setSettled","useState","useEffect","current","instance","publish","outcome","execute","enumerable","state","Object","entries","every","name","value","descriptors","parameterDescriptors","filter","descriptor","length","isEnumerable","type","String","Guid","setMicroservice","setApiBasePath","setOrigin","setHttpHeadersCallback","result","perform","isSuccess","isAuthorized","isValid","hasExceptions","isReady","data","undefined","Array","isArray","getOwnPropertyDescriptor","Number","isFinite","abortController","abort","_jsx","SingleResultStatus"],"mappings":"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"}
@@ -0,0 +1,141 @@
1
+ 'use strict';
2
+
3
+ var jsxRuntime = require('react/jsx-runtime');
4
+ var react = require('react');
5
+ var BindingKind = require('../bindings/BindingKind.js');
6
+ var bindingRegistry = require('../bindings/bindingRegistry.js');
7
+ require('../bindings/resolveElementBinding.js');
8
+ var MissingBinding = require('../bindings/MissingBinding.js');
9
+ var ArcRuntimeBoundary = require('../bindings/ArcRuntimeBoundary.js');
10
+ var properties = require('../properties.js');
11
+ var SingleResultStatus = require('../data/SingleResultStatus.js');
12
+ var queryInputs = require('./queryInputs.js');
13
+
14
+ const SingleResultRuntime = /*#__PURE__*/ react.lazy(()=>Promise.resolve().then(function () { return require('../data/SingleResultRuntime.js'); }));
15
+ /** Opt-in, form-local string drafts around the existing optional-single execution owner. */ function SceneQueryInputForm({ element }) {
16
+ const name = properties.stringProperty(element.properties, 'query');
17
+ const target = react.useSyncExternalStore(bindingRegistry.subscribeQueryBindings, ()=>name ? bindingRegistry.resolveExactQuery(name) : undefined);
18
+ if (target === 'ambiguous') return /*#__PURE__*/ jsxRuntime.jsxs("div", {
19
+ role: "alert",
20
+ children: [
21
+ "Ambiguous query binding '",
22
+ name,
23
+ "' on ",
24
+ element.componentName
25
+ ]
26
+ });
27
+ if (!target) return /*#__PURE__*/ jsxRuntime.jsx(MissingBinding.MissingBinding, {
28
+ element: element,
29
+ kind: BindingKind.BindingKind.Query,
30
+ name: name
31
+ });
32
+ const inputs = queryInputs.queryInputs(element.properties);
33
+ const resultField = properties.stringProperty(element.properties, 'resultField');
34
+ if (!inputs || !resultField) return /*#__PURE__*/ jsxRuntime.jsx("div", {
35
+ role: "alert",
36
+ children: "Invalid query input form configuration"
37
+ });
38
+ if (!element.isEnabled) return /*#__PURE__*/ jsxRuntime.jsx(SingleResultStatus.SingleResultStatus, {
39
+ state: "idle"
40
+ });
41
+ // A different form declaration starts a new session; ordinary host rerenders retain drafts.
42
+ return /*#__PURE__*/ jsxRuntime.jsx(QueryInputForm, {
43
+ query: target,
44
+ inputs: inputs,
45
+ resultField: resultField,
46
+ label: properties.stringProperty(element.properties, 'label') ?? 'Query input',
47
+ submitLabel: properties.stringProperty(element.properties, 'submitLabel') ?? 'Search'
48
+ }, JSON.stringify([
49
+ name,
50
+ inputs,
51
+ resultField
52
+ ]));
53
+ }
54
+ function QueryInputForm({ query, inputs, resultField, label, submitLabel }) {
55
+ const id = react.useId();
56
+ const [drafts, setDrafts] = react.useState(()=>Object.fromEntries(inputs.map((input)=>[
57
+ input.parameter,
58
+ ''
59
+ ])));
60
+ const [errors, setErrors] = react.useState({});
61
+ const [committed, setCommitted] = react.useState();
62
+ return /*#__PURE__*/ jsxRuntime.jsxs("form", {
63
+ "aria-label": label,
64
+ noValidate: true,
65
+ onSubmit: (event)=>{
66
+ event.preventDefault();
67
+ const validation = Object.fromEntries(inputs.map((input)=>[
68
+ input.parameter,
69
+ queryInputs.queryInputError(input, drafts[input.parameter])
70
+ ]));
71
+ setErrors(validation);
72
+ if (Object.values(validation).some(Boolean)) {
73
+ setCommitted(undefined);
74
+ return;
75
+ }
76
+ // New identity even for unchanged values: repeat submit is an explicit retry. No trimming,
77
+ // coercion, generated identifier, property-path evaluation or query while typing.
78
+ setCommitted(Object.freeze(Object.fromEntries(inputs.map((input)=>[
79
+ input.parameter,
80
+ drafts[input.parameter]
81
+ ]))));
82
+ },
83
+ children: [
84
+ inputs.map((input, index)=>{
85
+ const controlId = `${id}-${index}`;
86
+ const error = Object.hasOwn(errors, input.parameter) ? errors[input.parameter] : undefined;
87
+ return /*#__PURE__*/ jsxRuntime.jsxs("div", {
88
+ children: [
89
+ /*#__PURE__*/ jsxRuntime.jsx("label", {
90
+ htmlFor: controlId,
91
+ children: input.label
92
+ }),
93
+ /*#__PURE__*/ jsxRuntime.jsx("input", {
94
+ id: controlId,
95
+ name: input.parameter,
96
+ type: "text",
97
+ required: input.required,
98
+ value: drafts[input.parameter],
99
+ "aria-invalid": !!error,
100
+ "aria-describedby": error ? `${controlId}-error` : undefined,
101
+ onChange: (event)=>{
102
+ setDrafts({
103
+ ...drafts,
104
+ [input.parameter]: event.currentTarget.value
105
+ });
106
+ setErrors({
107
+ ...errors,
108
+ [input.parameter]: undefined
109
+ });
110
+ // Unmount synchronously on edit: runtime cleanup aborts and masks late replies.
111
+ setCommitted(undefined);
112
+ }
113
+ }),
114
+ error && /*#__PURE__*/ jsxRuntime.jsx("div", {
115
+ id: `${controlId}-error`,
116
+ role: "alert",
117
+ children: error
118
+ })
119
+ ]
120
+ }, input.parameter);
121
+ }),
122
+ /*#__PURE__*/ jsxRuntime.jsx("button", {
123
+ type: "submit",
124
+ children: submitLabel
125
+ }),
126
+ committed ? /*#__PURE__*/ jsxRuntime.jsx(ArcRuntimeBoundary.ArcRuntimeBoundary, {
127
+ children: /*#__PURE__*/ jsxRuntime.jsx(SingleResultRuntime, {
128
+ query: query,
129
+ queryArguments: committed,
130
+ resultField: resultField,
131
+ stringInputs: true
132
+ })
133
+ }) : /*#__PURE__*/ jsxRuntime.jsx(SingleResultStatus.SingleResultStatus, {
134
+ state: "idle"
135
+ })
136
+ ]
137
+ });
138
+ }
139
+
140
+ exports.SceneQueryInputForm = SceneQueryInputForm;
141
+ //# sourceMappingURL=SceneQueryInputForm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SceneQueryInputForm.js","sources":["../../../forms/SceneQueryInputForm.tsx"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { lazy, useId, useState, useSyncExternalStore } from 'react';\nimport { RegisteredComponentProps } from '@cratis/scene.react';\nimport { ArcRuntimeBoundary, BindingKind, BoundConstructor, MissingBinding, resolveExactQuery, subscribeQueryBindings } from '../bindings';\nimport { stringProperty } from '../properties';\nimport { SingleResultStatus } from '../data/SingleResultStatus';\nimport { QueryInput, queryInputError, queryInputs } from './queryInputs';\n\nconst SingleResultRuntime = lazy(() => import('../data/SingleResultRuntime'));\n\n/** Opt-in, form-local string drafts around the existing optional-single execution owner. */\nexport function SceneQueryInputForm({ element }: RegisteredComponentProps) {\n const name = stringProperty(element.properties, 'query');\n const target = useSyncExternalStore(subscribeQueryBindings, () => name ? resolveExactQuery(name) : undefined);\n if (target === 'ambiguous') return <div role='alert'>Ambiguous query binding '{name}' on {element.componentName}</div>;\n if (!target) return <MissingBinding element={element} kind={BindingKind.Query} name={name} />;\n\n const inputs = queryInputs(element.properties);\n const resultField = stringProperty(element.properties, 'resultField');\n if (!inputs || !resultField) return <div role='alert'>Invalid query input form configuration</div>;\n if (!element.isEnabled) return <SingleResultStatus state='idle' />;\n\n // A different form declaration starts a new session; ordinary host rerenders retain drafts.\n return <QueryInputForm key={JSON.stringify([name, inputs, resultField])}\n query={target} inputs={inputs} resultField={resultField}\n label={stringProperty(element.properties, 'label') ?? 'Query input'}\n submitLabel={stringProperty(element.properties, 'submitLabel') ?? 'Search'} />;\n}\n\ninterface Props {\n query: BoundConstructor;\n inputs: QueryInput[];\n resultField: string;\n label: string;\n submitLabel: string;\n}\n\nfunction QueryInputForm({ query, inputs, resultField, label, submitLabel }: Props) {\n const id = useId();\n const [drafts, setDrafts] = useState<Record<string, string>>(() => Object.fromEntries(inputs.map(input => [input.parameter, ''])));\n const [errors, setErrors] = useState<Record<string, string | undefined>>({});\n const [committed, setCommitted] = useState<Record<string, string>>();\n\n return <form aria-label={label} noValidate onSubmit={event => {\n event.preventDefault();\n const validation = Object.fromEntries(inputs.map(input => [input.parameter, queryInputError(input, drafts[input.parameter])]));\n setErrors(validation);\n if (Object.values(validation).some(Boolean)) {\n setCommitted(undefined);\n return;\n }\n // New identity even for unchanged values: repeat submit is an explicit retry. No trimming,\n // coercion, generated identifier, property-path evaluation or query while typing.\n setCommitted(Object.freeze(Object.fromEntries(inputs.map(input => [input.parameter, drafts[input.parameter]]))));\n }}>\n {inputs.map((input, index) => {\n const controlId = `${id}-${index}`;\n const error = Object.hasOwn(errors, input.parameter) ? errors[input.parameter] : undefined;\n return <div key={input.parameter}>\n <label htmlFor={controlId}>{input.label}</label>\n <input id={controlId} name={input.parameter} type='text' required={input.required}\n value={drafts[input.parameter]} aria-invalid={!!error} aria-describedby={error ? `${controlId}-error` : undefined}\n onChange={event => {\n setDrafts({ ...drafts, [input.parameter]: event.currentTarget.value });\n setErrors({ ...errors, [input.parameter]: undefined });\n // Unmount synchronously on edit: runtime cleanup aborts and masks late replies.\n setCommitted(undefined);\n }} />\n {error && <div id={`${controlId}-error`} role='alert'>{error}</div>}\n </div>;\n })}\n <button type='submit'>{submitLabel}</button>\n {committed ? <ArcRuntimeBoundary>\n <SingleResultRuntime query={query} queryArguments={committed} resultField={resultField} stringInputs />\n </ArcRuntimeBoundary> : <SingleResultStatus state='idle' />}\n </form>;\n}\n"],"names":["SingleResultRuntime","lazy","SceneQueryInputForm","element","name","stringProperty","properties","target","useSyncExternalStore","subscribeQueryBindings","resolveExactQuery","undefined","_jsxs","div","role","componentName","_jsx","MissingBinding","kind","BindingKind","Query","inputs","queryInputs","resultField","isEnabled","SingleResultStatus","state","QueryInputForm","query","label","submitLabel","JSON","stringify","id","useId","drafts","setDrafts","useState","Object","fromEntries","map","input","parameter","errors","setErrors","committed","setCommitted","form","aria-label","noValidate","onSubmit","event","preventDefault","validation","queryInputError","values","some","Boolean","freeze","index","controlId","error","hasOwn","htmlFor","type","required","value","aria-invalid","aria-describedby","onChange","currentTarget","button","ArcRuntimeBoundary","queryArguments","stringInputs"],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ 'use strict';
2
+
3
+ var properties = require('../properties.js');
4
+
5
+ // Copyright (c) Cratis. All rights reserved.
6
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
7
+ /** Reject the entire declaration rather than silently dropping malformed inputs. */ function queryInputs(properties$1) {
8
+ const values = properties.arrayProperty(properties$1, 'inputs');
9
+ if (!values?.length) return undefined;
10
+ const inputs = [];
11
+ const parameters = new Set();
12
+ for (const value of values){
13
+ const input = properties.objectProperty({
14
+ value
15
+ }, 'value');
16
+ if (!input) return undefined;
17
+ const parameter = properties.stringProperty(input, 'parameter');
18
+ const label = properties.stringProperty(input, 'label');
19
+ const required = properties.booleanProperty(input, 'required');
20
+ const pattern = properties.stringProperty(input, 'pattern');
21
+ if (!parameter || !label || input.type !== 'string' || parameters.has(parameter) || input.required !== undefined && required === undefined || input.pattern !== undefined && pattern === undefined) return undefined;
22
+ if (pattern !== undefined) {
23
+ try {
24
+ new RegExp(`^(?:${pattern})$`, 'u');
25
+ } catch {
26
+ return undefined;
27
+ }
28
+ }
29
+ parameters.add(parameter);
30
+ inputs.push({
31
+ parameter,
32
+ type: 'string',
33
+ label,
34
+ required: required ?? true,
35
+ pattern
36
+ });
37
+ }
38
+ return inputs;
39
+ }
40
+ /** Validation never transforms the submitted string; proxy validators remain authoritative. */ function queryInputError(input, value) {
41
+ if (input.required && !/\S/u.test(value)) return `${input.label} is required`;
42
+ if (input.pattern !== undefined && !new RegExp(`^(?:${input.pattern})$`, 'u').test(value)) {
43
+ return `${input.label} has an invalid format`;
44
+ }
45
+ return undefined;
46
+ }
47
+
48
+ exports.queryInputError = queryInputError;
49
+ exports.queryInputs = queryInputs;
50
+ //# sourceMappingURL=queryInputs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queryInputs.js","sources":["../../../forms/queryInputs.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { arrayProperty, booleanProperty, objectProperty, stringProperty } from '../properties';\n\n/** Package-local web input declaration, not a Scene.Model form or binding expression. */\nexport interface QueryInput {\n /** Exact generated query argument name. */\n parameter: string;\n type: 'string';\n label: string;\n /** Defaults to true. Required strings must contain a non-whitespace character. */\n required?: boolean;\n /** Optional whole-value JavaScript Unicode regular expression (without delimiters). */\n pattern?: string;\n}\n\n/** Reject the entire declaration rather than silently dropping malformed inputs. */\nexport function queryInputs(properties: Record<string, unknown>): QueryInput[] | undefined {\n const values = arrayProperty(properties, 'inputs');\n if (!values?.length) return undefined;\n const inputs: QueryInput[] = [];\n const parameters = new Set<string>();\n for (const value of values) {\n const input = objectProperty({ value }, 'value');\n if (!input) return undefined;\n const parameter = stringProperty(input, 'parameter');\n const label = stringProperty(input, 'label');\n const required = booleanProperty(input, 'required');\n const pattern = stringProperty(input, 'pattern');\n if (!parameter || !label || input.type !== 'string' || parameters.has(parameter)\n || (input.required !== undefined && required === undefined)\n || (input.pattern !== undefined && pattern === undefined)) return undefined;\n if (pattern !== undefined) {\n try { new RegExp(`^(?:${pattern})$`, 'u'); } catch { return undefined; }\n }\n parameters.add(parameter);\n inputs.push({ parameter, type: 'string', label, required: required ?? true, pattern });\n }\n return inputs;\n}\n\n/** Validation never transforms the submitted string; proxy validators remain authoritative. */\nexport function queryInputError(input: QueryInput, value: string): string | undefined {\n if (input.required && !/\\S/u.test(value)) return `${input.label} is required`;\n if (input.pattern !== undefined && !new RegExp(`^(?:${input.pattern})$`, 'u').test(value)) {\n return `${input.label} has an invalid format`;\n }\n return undefined;\n}\n"],"names":["queryInputs","properties","values","arrayProperty","length","undefined","inputs","parameters","Set","value","input","objectProperty","parameter","stringProperty","label","required","booleanProperty","pattern","type","has","RegExp","add","push","queryInputError","test"],"mappings":";;;;AAAA;AACA;AAgBA,qFACO,SAASA,WAAAA,CAAYC,YAAmC,EAAA;IAC3D,MAAMC,MAAAA,GAASC,yBAAcF,YAAAA,EAAY,QAAA,CAAA;IACzC,IAAI,CAACC,MAAAA,EAAQE,MAAAA,EAAQ,OAAOC,SAAAA;AAC5B,IAAA,MAAMC,SAAuB,EAAE;AAC/B,IAAA,MAAMC,aAAa,IAAIC,GAAAA,EAAAA;IACvB,KAAK,MAAMC,SAASP,MAAAA,CAAQ;AACxB,QAAA,MAAMQ,QAAQC,yBAAAA,CAAe;AAAEF,YAAAA;SAAM,EAAG,OAAA,CAAA;QACxC,IAAI,CAACC,OAAO,OAAOL,SAAAA;QACnB,MAAMO,SAAAA,GAAYC,0BAAeH,KAAAA,EAAO,WAAA,CAAA;QACxC,MAAMI,KAAAA,GAAQD,0BAAeH,KAAAA,EAAO,OAAA,CAAA;QACpC,MAAMK,QAAAA,GAAWC,2BAAgBN,KAAAA,EAAO,UAAA,CAAA;QACxC,MAAMO,OAAAA,GAAUJ,0BAAeH,KAAAA,EAAO,SAAA,CAAA;QACtC,IAAI,CAACE,SAAAA,IAAa,CAACE,KAAAA,IAASJ,KAAAA,CAAMQ,IAAI,KAAK,QAAA,IAAYX,UAAAA,CAAWY,GAAG,CAACP,SAAAA,CAAAA,IAC9DF,MAAMK,QAAQ,KAAKV,SAAAA,IAAaU,QAAAA,KAAaV,SAAAA,IAC7CK,KAAAA,CAAMO,OAAO,KAAKZ,SAAAA,IAAaY,OAAAA,KAAYZ,SAAAA,EAAY,OAAOA,SAAAA;AACtE,QAAA,IAAIY,YAAYZ,SAAAA,EAAW;YACvB,IAAI;AAAE,gBAAA,IAAIe,OAAO,CAAC,IAAI,EAAEH,OAAAA,CAAQ,EAAE,CAAC,EAAE,GAAA,CAAA;AAAM,YAAA,CAAA,CAAE,OAAM;gBAAE,OAAOZ,SAAAA;AAAW,YAAA;AAC3E,QAAA;AACAE,QAAAA,UAAAA,CAAWc,GAAG,CAACT,SAAAA,CAAAA;AACfN,QAAAA,MAAAA,CAAOgB,IAAI,CAAC;AAAEV,YAAAA,SAAAA;YAAWM,IAAAA,EAAM,QAAA;AAAUJ,YAAAA,KAAAA;AAAOC,YAAAA,QAAAA,EAAUA,QAAAA,IAAY,IAAA;AAAME,YAAAA;AAAQ,SAAA,CAAA;AACxF,IAAA;IACA,OAAOX,MAAAA;AACX;AAEA,gGACO,SAASiB,eAAAA,CAAgBb,KAAiB,EAAED,KAAa,EAAA;AAC5D,IAAA,IAAIC,KAAAA,CAAMK,QAAQ,IAAI,CAAC,MAAMS,IAAI,CAACf,KAAAA,CAAAA,EAAQ,OAAO,CAAA,EAAGC,KAAAA,CAAMI,KAAK,CAAC,YAAY,CAAC;AAC7E,IAAA,IAAIJ,MAAMO,OAAO,KAAKZ,aAAa,CAAC,IAAIe,OAAO,CAAC,IAAI,EAAEV,KAAAA,CAAMO,OAAO,CAAC,EAAE,CAAC,EAAE,GAAA,CAAA,CAAKO,IAAI,CAACf,KAAAA,CAAAA,EAAQ;AACvF,QAAA,OAAO,CAAA,EAAGC,KAAAA,CAAMI,KAAK,CAAC,sBAAsB,CAAC;AACjD,IAAA;IACA,OAAOT,SAAAA;AACX;;;"}
package/dist/cjs/index.js CHANGED
@@ -14,6 +14,7 @@ var SceneSingleResult = require('./data/SceneSingleResult.js');
14
14
  var SceneDataTable = require('./data/SceneDataTable.js');
15
15
  var SceneObservableDataTable = require('./data/SceneObservableDataTable.js');
16
16
  var SceneCommandForm = require('./forms/SceneCommandForm.js');
17
+ var SceneQueryInputForm = require('./forms/SceneQueryInputForm.js');
17
18
  var resolveFieldBinding = require('./forms/fields/resolveFieldBinding.js');
18
19
  var CommandFormField = require('./forms/fields/CommandFormField.js');
19
20
  var SceneInputTextField = require('./forms/fields/SceneInputTextField.js');
@@ -68,10 +69,14 @@ exports.registerCommand = bindingRegistry.registerCommand;
68
69
  exports.registerCommands = bindingRegistry.registerCommands;
69
70
  exports.registerQueries = bindingRegistry.registerQueries;
70
71
  exports.registerQuery = bindingRegistry.registerQuery;
72
+ exports.registerQueryIdentity = bindingRegistry.registerQueryIdentity;
71
73
  exports.registeredCommandNames = bindingRegistry.registeredCommandNames;
72
74
  exports.registeredQueryNames = bindingRegistry.registeredQueryNames;
73
75
  exports.resolveCommand = bindingRegistry.resolveCommand;
76
+ exports.resolveExactQuery = bindingRegistry.resolveExactQuery;
74
77
  exports.resolveQuery = bindingRegistry.resolveQuery;
78
+ exports.subscribeQueryBindings = bindingRegistry.subscribeQueryBindings;
79
+ exports.unregisterQueryIdentity = bindingRegistry.unregisterQueryIdentity;
75
80
  exports.resolveElementBinding = resolveElementBinding.resolveElementBinding;
76
81
  exports.Placeholder = Placeholder.Placeholder;
77
82
  exports.MissingBinding = MissingBinding.MissingBinding;
@@ -83,6 +88,7 @@ exports.SceneSingleResult = SceneSingleResult.SceneSingleResult;
83
88
  exports.SceneDataTable = SceneDataTable.SceneDataTable;
84
89
  exports.SceneObservableDataTable = SceneObservableDataTable.SceneObservableDataTable;
85
90
  exports.SceneCommandForm = SceneCommandForm.SceneCommandForm;
91
+ exports.SceneQueryInputForm = SceneQueryInputForm.SceneQueryInputForm;
86
92
  exports.resolveFieldBinding = resolveFieldBinding.resolveFieldBinding;
87
93
  exports.CommandFormField = CommandFormField.CommandFormField;
88
94
  exports.SceneInputTextField = SceneInputTextField.SceneInputTextField;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,4 +1,8 @@
1
1
  import { BoundConstructor } from './BoundConstructor';
2
+ export declare function subscribeQueryBindings(listener: () => void): () => void;
3
+ export declare function registerQueryIdentity(name: string, identity: string, queryClass: BoundConstructor): void;
4
+ export declare function unregisterQueryIdentity(name: string, identity: string): void;
5
+ export declare function resolveExactQuery(name: string): BoundConstructor | 'ambiguous' | undefined;
2
6
  export declare function registerQuery(name: string, queryClass: BoundConstructor): void;
3
7
  export declare function registerQueries(bindings: Record<string, BoundConstructor>): void;
4
8
  export declare function resolveQuery(name: string): BoundConstructor | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"bindingRegistry.d.ts","sourceRoot":"","sources":["../../../bindings/bindingRegistry.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAqBtD,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,gBAAgB,GAAG,IAAI,CAE9E;AASD,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,GAAG,IAAI,CAIhF;AASD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS,CAEvE;AAMD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,gBAAgB,GAAG,IAAI,CAElF;AAKD,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,GAAG,IAAI,CAIjF;AAKD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS,CAEzE;AASD,wBAAgB,oBAAoB,IAAI,MAAM,EAAE,CAE/C;AAKD,wBAAgB,sBAAsB,IAAI,MAAM,EAAE,CAEjD;AASD,wBAAgB,aAAa,IAAI,IAAI,CAGpC"}
1
+ {"version":3,"file":"bindingRegistry.d.ts","sourceRoot":"","sources":["../../../bindings/bindingRegistry.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAatD,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAGvE;AAOD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,gBAAgB,GAAG,IAAI,CAKxG;AAGD,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAK5E;AAGD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,GAAG,WAAW,GAAG,SAAS,CAK1F;AAkBD,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,gBAAgB,GAAG,IAAI,CAG9E;AASD,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,GAAG,IAAI,CAIhF;AAUD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS,CAKvE;AAMD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,gBAAgB,GAAG,IAAI,CAElF;AAKD,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,GAAG,IAAI,CAIjF;AAKD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS,CAEzE;AASD,wBAAgB,oBAAoB,IAAI,MAAM,EAAE,CAE/C;AAKD,wBAAgB,sBAAsB,IAAI,MAAM,EAAE,CAEjD;AASD,wBAAgB,aAAa,IAAI,IAAI,CAKpC"}
@@ -2,6 +2,40 @@
2
2
  // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
3
  const queries = new Map();
4
4
  const commands = new Map();
5
+ // Opt-in identities are separate from the legacy last-registration-wins namespace.
6
+ const queryIdentities = new Map();
7
+ const queryBindingListeners = new Set();
8
+ function notifyQueryBindings() {
9
+ for (const listener of queryBindingListeners)listener();
10
+ }
11
+ /** Subscribe to exact-binding changes. Existing adapters retain their render-time lookup contract. */ function subscribeQueryBindings(listener) {
12
+ queryBindingListeners.add(listener);
13
+ return ()=>{
14
+ queryBindingListeners.delete(listener);
15
+ };
16
+ }
17
+ /**
18
+ * Registers one source identity for an exact query name. The same identity replaces on hot reload;
19
+ * different identities remain distinct candidates, even when their constructors happen to match.
20
+ * Legacy resolution also accepts a unique identity when no legacy registration exists.
21
+ */ function registerQueryIdentity(name, identity, queryClass) {
22
+ const candidates = queryIdentities.get(name) ?? new Map();
23
+ candidates.set(identity, queryClass);
24
+ queryIdentities.set(name, candidates);
25
+ notifyQueryBindings();
26
+ }
27
+ /** Removes a source identity when a generated module is removed or renamed. */ function unregisterQueryIdentity(name, identity) {
28
+ const candidates = queryIdentities.get(name);
29
+ candidates?.delete(identity);
30
+ if (candidates?.size === 0) queryIdentities.delete(name);
31
+ notifyQueryBindings();
32
+ }
33
+ /** Exact binding: a legacy registration counts as one candidate alongside opt-in identities. */ function resolveExactQuery(name) {
34
+ const legacy = queries.get(name);
35
+ const candidates = queryIdentities.get(name);
36
+ if ((legacy ? 1 : 0) + (candidates?.size ?? 0) > 1) return 'ambiguous';
37
+ return legacy ?? candidates?.values().next().value;
38
+ }
5
39
  /**
6
40
  * Registers an Arc query proxy under the name screens refer to it by.
7
41
  *
@@ -19,6 +53,7 @@ const commands = new Map();
19
53
  * the previous run.
20
54
  */ function registerQuery(name, queryClass) {
21
55
  queries.set(name, queryClass);
56
+ notifyQueryBindings();
22
57
  }
23
58
  /**
24
59
  * Registers several query proxies at once, keyed by the name screens refer to each by.
@@ -32,13 +67,17 @@ const commands = new Map();
32
67
  }
33
68
  }
34
69
  /**
35
- * The query proxy registered under a name, or `undefined` when nothing is registered under it.
70
+ * Legacy registrations are authoritative. Otherwise resolve a unique source identity, or `undefined`
71
+ * when absent or ambiguous (existing adapters display their unresolved-binding placeholder).
36
72
  *
37
73
  * `undefined` rather than a throw: design-time preview in Studio normally has nothing registered at all,
38
74
  * and a screen still has to render so its layout can be worked on. Every adapter turns `undefined` into
39
75
  * a visible placeholder naming the binding it wanted.
40
76
  */ function resolveQuery(name) {
41
- return queries.get(name);
77
+ const legacy = queries.get(name);
78
+ if (legacy) return legacy;
79
+ const candidates = queryIdentities.get(name);
80
+ return candidates?.size === 1 ? candidates.values().next().value : undefined;
42
81
  }
43
82
  /**
44
83
  * Registers an Arc command proxy under the name screens refer to it by. The command half of
@@ -59,14 +98,17 @@ const commands = new Map();
59
98
  return commands.get(name);
60
99
  }
61
100
  /**
62
- * Every registered query name, sorted.
101
+ * The sorted union of legacy and identity query names, including ambiguous names.
63
102
  *
64
103
  * A design-time tool uses this to offer the names a screen can actually bind to, and a diagnostics
65
104
  * surface uses it to explain a placeholder - "this screen wants `AllInvoices`, and here is what is
66
105
  * registered" is a far more useful message than the placeholder alone.
67
106
  */ function registeredQueryNames() {
68
107
  return [
69
- ...queries.keys()
108
+ ...new Set([
109
+ ...queries.keys(),
110
+ ...queryIdentities.keys()
111
+ ])
70
112
  ].sort();
71
113
  }
72
114
  /**
@@ -85,7 +127,9 @@ const commands = new Map();
85
127
  */ function clearBindings() {
86
128
  queries.clear();
87
129
  commands.clear();
130
+ queryIdentities.clear();
131
+ notifyQueryBindings();
88
132
  }
89
133
 
90
- export { clearBindings, registerCommand, registerCommands, registerQueries, registerQuery, registeredCommandNames, registeredQueryNames, resolveCommand, resolveQuery };
134
+ export { clearBindings, registerCommand, registerCommands, registerQueries, registerQuery, registerQueryIdentity, registeredCommandNames, registeredQueryNames, resolveCommand, resolveExactQuery, resolveQuery, subscribeQueryBindings, unregisterQueryIdentity };
91
135
  //# sourceMappingURL=bindingRegistry.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"bindingRegistry.js","sources":["../../../bindings/bindingRegistry.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { BoundConstructor } from './BoundConstructor';\n\nconst queries = new Map<string, BoundConstructor>();\nconst commands = new Map<string, BoundConstructor>();\n\n/**\n * Registers an Arc query proxy under the name screens refer to it by.\n *\n * This is the seam that makes the Arc-bound half of `@cratis/components` usable from Scene at all. A\n * screen says `data Invoices via query AllInvoices`, and by the time that reaches a renderer it is an\n * `ExternalComponent` whose `properties` bag holds the *string* `'AllInvoices'` - a property bag carries\n * plain values and named slots, and there is no way to put a TypeScript class into one. `DataTableForQuery`\n * needs the class. The name is the only thing that survives the trip, so the name is what the lookup has\n * to be keyed on, and a host that owns the generated proxies is the only party that can supply the class\n * behind it.\n *\n * A host - Stage's generated application, or Studio's preview when it is wired to a real backend -\n * registers every proxy a screen can name, once, during startup. Registering the same name twice\n * replaces the earlier registration, so a host can re-register on hot reload without having to unwind\n * the previous run.\n */\nexport function registerQuery(name: string, queryClass: BoundConstructor): void {\n queries.set(name, queryClass);\n}\n\n/**\n * Registers several query proxies at once, keyed by the name screens refer to each by.\n *\n * Stage generates a module that exports every proxy it produced; handing that module's exports straight\n * to this is the whole of a generated host's registration step, and it stays correct as proxies are\n * added and removed without anyone editing a list.\n */\nexport function registerQueries(bindings: Record<string, BoundConstructor>): void {\n for (const [name, queryClass] of Object.entries(bindings)) {\n registerQuery(name, queryClass);\n }\n}\n\n/**\n * The query proxy registered under a name, or `undefined` when nothing is registered under it.\n *\n * `undefined` rather than a throw: design-time preview in Studio normally has nothing registered at all,\n * and a screen still has to render so its layout can be worked on. Every adapter turns `undefined` into\n * a visible placeholder naming the binding it wanted.\n */\nexport function resolveQuery(name: string): BoundConstructor | undefined {\n return queries.get(name);\n}\n\n/**\n * Registers an Arc command proxy under the name screens refer to it by. The command half of\n * {@link registerQuery}, with the same contract.\n */\nexport function registerCommand(name: string, commandClass: BoundConstructor): void {\n commands.set(name, commandClass);\n}\n\n/**\n * Registers several command proxies at once, keyed by the name screens refer to each by.\n */\nexport function registerCommands(bindings: Record<string, BoundConstructor>): void {\n for (const [name, commandClass] of Object.entries(bindings)) {\n registerCommand(name, commandClass);\n }\n}\n\n/**\n * The command proxy registered under a name, or `undefined` when nothing is registered under it.\n */\nexport function resolveCommand(name: string): BoundConstructor | undefined {\n return commands.get(name);\n}\n\n/**\n * Every registered query name, sorted.\n *\n * A design-time tool uses this to offer the names a screen can actually bind to, and a diagnostics\n * surface uses it to explain a placeholder - \"this screen wants `AllInvoices`, and here is what is\n * registered\" is a far more useful message than the placeholder alone.\n */\nexport function registeredQueryNames(): string[] {\n return [...queries.keys()].sort();\n}\n\n/**\n * Every registered command name, sorted.\n */\nexport function registeredCommandNames(): string[] {\n return [...commands.keys()].sort();\n}\n\n/**\n * Forgets every registered query and command.\n *\n * The registry is module-level state, which is right for a host that registers once at startup but wrong\n * for anything that switches between applications - Studio previewing a different project, or a spec\n * that must not inherit what the previous one registered. Both need a way back to empty.\n */\nexport function clearBindings(): void {\n queries.clear();\n commands.clear();\n}\n"],"names":["queries","Map","commands","registerQuery","name","queryClass","set","registerQueries","bindings","Object","entries","resolveQuery","get","registerCommand","commandClass","registerCommands","resolveCommand","registeredQueryNames","keys","sort","registeredCommandNames","clearBindings","clear"],"mappings":"AAAA;AACA;AAIA,MAAMA,UAAU,IAAIC,GAAAA,EAAAA;AACpB,MAAMC,WAAW,IAAID,GAAAA,EAAAA;AAErB;;;;;;;;;;;;;;;AAeC,IACM,SAASE,aAAAA,CAAcC,IAAY,EAAEC,UAA4B,EAAA;IACpEL,OAAAA,CAAQM,GAAG,CAACF,IAAAA,EAAMC,UAAAA,CAAAA;AACtB;AAEA;;;;;;IAOO,SAASE,eAAAA,CAAgBC,QAA0C,EAAA;IACtE,KAAK,MAAM,CAACJ,IAAAA,EAAMC,UAAAA,CAAW,IAAII,MAAAA,CAAOC,OAAO,CAACF,QAAAA,CAAAA,CAAW;AACvDL,QAAAA,aAAAA,CAAcC,IAAAA,EAAMC,UAAAA,CAAAA;AACxB,IAAA;AACJ;AAEA;;;;;;IAOO,SAASM,YAAAA,CAAaP,IAAY,EAAA;IACrC,OAAOJ,OAAAA,CAAQY,GAAG,CAACR,IAAAA,CAAAA;AACvB;AAEA;;;AAGC,IACM,SAASS,eAAAA,CAAgBT,IAAY,EAAEU,YAA8B,EAAA;IACxEZ,QAAAA,CAASI,GAAG,CAACF,IAAAA,EAAMU,YAAAA,CAAAA;AACvB;AAEA;;IAGO,SAASC,gBAAAA,CAAiBP,QAA0C,EAAA;IACvE,KAAK,MAAM,CAACJ,IAAAA,EAAMU,YAAAA,CAAa,IAAIL,MAAAA,CAAOC,OAAO,CAACF,QAAAA,CAAAA,CAAW;AACzDK,QAAAA,eAAAA,CAAgBT,IAAAA,EAAMU,YAAAA,CAAAA;AAC1B,IAAA;AACJ;AAEA;;IAGO,SAASE,cAAAA,CAAeZ,IAAY,EAAA;IACvC,OAAOF,QAAAA,CAASU,GAAG,CAACR,IAAAA,CAAAA;AACxB;AAEA;;;;;;AAMC,IACM,SAASa,oBAAAA,GAAAA;IACZ,OAAO;AAAIjB,QAAAA,GAAAA,OAAAA,CAAQkB,IAAI;AAAG,KAAA,CAACC,IAAI,EAAA;AACnC;AAEA;;AAEC,IACM,SAASC,sBAAAA,GAAAA;IACZ,OAAO;AAAIlB,QAAAA,GAAAA,QAAAA,CAASgB,IAAI;AAAG,KAAA,CAACC,IAAI,EAAA;AACpC;AAEA;;;;;;AAMC,IACM,SAASE,aAAAA,GAAAA;AACZrB,IAAAA,OAAAA,CAAQsB,KAAK,EAAA;AACbpB,IAAAA,QAAAA,CAASoB,KAAK,EAAA;AAClB;;"}
1
+ {"version":3,"file":"bindingRegistry.js","sources":["../../../bindings/bindingRegistry.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { BoundConstructor } from './BoundConstructor';\n\nconst queries = new Map<string, BoundConstructor>();\nconst commands = new Map<string, BoundConstructor>();\n// Opt-in identities are separate from the legacy last-registration-wins namespace.\nconst queryIdentities = new Map<string, Map<string, BoundConstructor>>();\nconst queryBindingListeners = new Set<() => void>();\n\nfunction notifyQueryBindings(): void {\n for (const listener of queryBindingListeners) listener();\n}\n\n/** Subscribe to exact-binding changes. Existing adapters retain their render-time lookup contract. */\nexport function subscribeQueryBindings(listener: () => void): () => void {\n queryBindingListeners.add(listener);\n return () => { queryBindingListeners.delete(listener); };\n}\n\n/**\n * Registers one source identity for an exact query name. The same identity replaces on hot reload;\n * different identities remain distinct candidates, even when their constructors happen to match.\n * Legacy resolution also accepts a unique identity when no legacy registration exists.\n */\nexport function registerQueryIdentity(name: string, identity: string, queryClass: BoundConstructor): void {\n const candidates = queryIdentities.get(name) ?? new Map<string, BoundConstructor>();\n candidates.set(identity, queryClass);\n queryIdentities.set(name, candidates);\n notifyQueryBindings();\n}\n\n/** Removes a source identity when a generated module is removed or renamed. */\nexport function unregisterQueryIdentity(name: string, identity: string): void {\n const candidates = queryIdentities.get(name);\n candidates?.delete(identity);\n if (candidates?.size === 0) queryIdentities.delete(name);\n notifyQueryBindings();\n}\n\n/** Exact binding: a legacy registration counts as one candidate alongside opt-in identities. */\nexport function resolveExactQuery(name: string): BoundConstructor | 'ambiguous' | undefined {\n const legacy = queries.get(name);\n const candidates = queryIdentities.get(name);\n if ((legacy ? 1 : 0) + (candidates?.size ?? 0) > 1) return 'ambiguous';\n return legacy ?? candidates?.values().next().value;\n}\n\n/**\n * Registers an Arc query proxy under the name screens refer to it by.\n *\n * This is the seam that makes the Arc-bound half of `@cratis/components` usable from Scene at all. A\n * screen says `data Invoices via query AllInvoices`, and by the time that reaches a renderer it is an\n * `ExternalComponent` whose `properties` bag holds the *string* `'AllInvoices'` - a property bag carries\n * plain values and named slots, and there is no way to put a TypeScript class into one. `DataTableForQuery`\n * needs the class. The name is the only thing that survives the trip, so the name is what the lookup has\n * to be keyed on, and a host that owns the generated proxies is the only party that can supply the class\n * behind it.\n *\n * A host - Stage's generated application, or Studio's preview when it is wired to a real backend -\n * registers every proxy a screen can name, once, during startup. Registering the same name twice\n * replaces the earlier registration, so a host can re-register on hot reload without having to unwind\n * the previous run.\n */\nexport function registerQuery(name: string, queryClass: BoundConstructor): void {\n queries.set(name, queryClass);\n notifyQueryBindings();\n}\n\n/**\n * Registers several query proxies at once, keyed by the name screens refer to each by.\n *\n * Stage generates a module that exports every proxy it produced; handing that module's exports straight\n * to this is the whole of a generated host's registration step, and it stays correct as proxies are\n * added and removed without anyone editing a list.\n */\nexport function registerQueries(bindings: Record<string, BoundConstructor>): void {\n for (const [name, queryClass] of Object.entries(bindings)) {\n registerQuery(name, queryClass);\n }\n}\n\n/**\n * Legacy registrations are authoritative. Otherwise resolve a unique source identity, or `undefined`\n * when absent or ambiguous (existing adapters display their unresolved-binding placeholder).\n *\n * `undefined` rather than a throw: design-time preview in Studio normally has nothing registered at all,\n * and a screen still has to render so its layout can be worked on. Every adapter turns `undefined` into\n * a visible placeholder naming the binding it wanted.\n */\nexport function resolveQuery(name: string): BoundConstructor | undefined {\n const legacy = queries.get(name);\n if (legacy) return legacy;\n const candidates = queryIdentities.get(name);\n return candidates?.size === 1 ? candidates.values().next().value : undefined;\n}\n\n/**\n * Registers an Arc command proxy under the name screens refer to it by. The command half of\n * {@link registerQuery}, with the same contract.\n */\nexport function registerCommand(name: string, commandClass: BoundConstructor): void {\n commands.set(name, commandClass);\n}\n\n/**\n * Registers several command proxies at once, keyed by the name screens refer to each by.\n */\nexport function registerCommands(bindings: Record<string, BoundConstructor>): void {\n for (const [name, commandClass] of Object.entries(bindings)) {\n registerCommand(name, commandClass);\n }\n}\n\n/**\n * The command proxy registered under a name, or `undefined` when nothing is registered under it.\n */\nexport function resolveCommand(name: string): BoundConstructor | undefined {\n return commands.get(name);\n}\n\n/**\n * The sorted union of legacy and identity query names, including ambiguous names.\n *\n * A design-time tool uses this to offer the names a screen can actually bind to, and a diagnostics\n * surface uses it to explain a placeholder - \"this screen wants `AllInvoices`, and here is what is\n * registered\" is a far more useful message than the placeholder alone.\n */\nexport function registeredQueryNames(): string[] {\n return [...new Set([...queries.keys(), ...queryIdentities.keys()])].sort();\n}\n\n/**\n * Every registered command name, sorted.\n */\nexport function registeredCommandNames(): string[] {\n return [...commands.keys()].sort();\n}\n\n/**\n * Forgets every registered query and command.\n *\n * The registry is module-level state, which is right for a host that registers once at startup but wrong\n * for anything that switches between applications - Studio previewing a different project, or a spec\n * that must not inherit what the previous one registered. Both need a way back to empty.\n */\nexport function clearBindings(): void {\n queries.clear();\n commands.clear();\n queryIdentities.clear();\n notifyQueryBindings();\n}\n"],"names":["queries","Map","commands","queryIdentities","queryBindingListeners","Set","notifyQueryBindings","listener","subscribeQueryBindings","add","delete","registerQueryIdentity","name","identity","queryClass","candidates","get","set","unregisterQueryIdentity","size","resolveExactQuery","legacy","values","next","value","registerQuery","registerQueries","bindings","Object","entries","resolveQuery","undefined","registerCommand","commandClass","registerCommands","resolveCommand","registeredQueryNames","keys","sort","registeredCommandNames","clearBindings","clear"],"mappings":"AAAA;AACA;AAIA,MAAMA,UAAU,IAAIC,GAAAA,EAAAA;AACpB,MAAMC,WAAW,IAAID,GAAAA,EAAAA;AACrB;AACA,MAAME,kBAAkB,IAAIF,GAAAA,EAAAA;AAC5B,MAAMG,wBAAwB,IAAIC,GAAAA,EAAAA;AAElC,SAASC,mBAAAA,GAAAA;IACL,KAAK,MAAMC,YAAYH,qBAAAA,CAAuBG,QAAAA,EAAAA;AAClD;AAEA,uGACO,SAASC,sBAAAA,CAAuBD,QAAoB,EAAA;AACvDH,IAAAA,qBAAAA,CAAsBK,GAAG,CAACF,QAAAA,CAAAA;IAC1B,OAAO,IAAA;AAAQH,QAAAA,qBAAAA,CAAsBM,MAAM,CAACH,QAAAA,CAAAA;AAAW,IAAA,CAAA;AAC3D;AAEA;;;;AAIC,IACM,SAASI,qBAAAA,CAAsBC,IAAY,EAAEC,QAAgB,EAAEC,UAA4B,EAAA;AAC9F,IAAA,MAAMC,UAAAA,GAAaZ,eAAAA,CAAgBa,GAAG,CAACJ,SAAS,IAAIX,GAAAA,EAAAA;IACpDc,UAAAA,CAAWE,GAAG,CAACJ,QAAAA,EAAUC,UAAAA,CAAAA;IACzBX,eAAAA,CAAgBc,GAAG,CAACL,IAAAA,EAAMG,UAAAA,CAAAA;AAC1BT,IAAAA,mBAAAA,EAAAA;AACJ;AAEA,gFACO,SAASY,uBAAAA,CAAwBN,IAAY,EAAEC,QAAgB,EAAA;IAClE,MAAME,UAAAA,GAAaZ,eAAAA,CAAgBa,GAAG,CAACJ,IAAAA,CAAAA;AACvCG,IAAAA,UAAAA,EAAYL,MAAAA,CAAOG,QAAAA,CAAAA;AACnB,IAAA,IAAIE,UAAAA,EAAYI,IAAAA,KAAS,CAAA,EAAGhB,eAAAA,CAAgBO,MAAM,CAACE,IAAAA,CAAAA;AACnDN,IAAAA,mBAAAA,EAAAA;AACJ;AAEA,iGACO,SAASc,iBAAAA,CAAkBR,IAAY,EAAA;IAC1C,MAAMS,MAAAA,GAASrB,OAAAA,CAAQgB,GAAG,CAACJ,IAAAA,CAAAA;IAC3B,MAAMG,UAAAA,GAAaZ,eAAAA,CAAgBa,GAAG,CAACJ,IAAAA,CAAAA;AACvC,IAAA,IAAI,CAACS,MAAAA,GAAS,CAAA,GAAI,CAAA,KAAMN,UAAAA,EAAYI,IAAAA,IAAQ,CAAA,CAAA,GAAK,CAAA,EAAG,OAAO,WAAA;IAC3D,OAAOE,MAAAA,IAAUN,UAAAA,EAAYO,MAAAA,EAAAA,CAASC,IAAAA,EAAAA,CAAOC,KAAAA;AACjD;AAEA;;;;;;;;;;;;;;;AAeC,IACM,SAASC,aAAAA,CAAcb,IAAY,EAAEE,UAA4B,EAAA;IACpEd,OAAAA,CAAQiB,GAAG,CAACL,IAAAA,EAAME,UAAAA,CAAAA;AAClBR,IAAAA,mBAAAA,EAAAA;AACJ;AAEA;;;;;;IAOO,SAASoB,eAAAA,CAAgBC,QAA0C,EAAA;IACtE,KAAK,MAAM,CAACf,IAAAA,EAAME,UAAAA,CAAW,IAAIc,MAAAA,CAAOC,OAAO,CAACF,QAAAA,CAAAA,CAAW;AACvDF,QAAAA,aAAAA,CAAcb,IAAAA,EAAME,UAAAA,CAAAA;AACxB,IAAA;AACJ;AAEA;;;;;;;IAQO,SAASgB,YAAAA,CAAalB,IAAY,EAAA;IACrC,MAAMS,MAAAA,GAASrB,OAAAA,CAAQgB,GAAG,CAACJ,IAAAA,CAAAA;AAC3B,IAAA,IAAIS,QAAQ,OAAOA,MAAAA;IACnB,MAAMN,UAAAA,GAAaZ,eAAAA,CAAgBa,GAAG,CAACJ,IAAAA,CAAAA;IACvC,OAAOG,UAAAA,EAAYI,SAAS,CAAA,GAAIJ,UAAAA,CAAWO,MAAM,EAAA,CAAGC,IAAI,EAAA,CAAGC,KAAK,GAAGO,SAAAA;AACvE;AAEA;;;AAGC,IACM,SAASC,eAAAA,CAAgBpB,IAAY,EAAEqB,YAA8B,EAAA;IACxE/B,QAAAA,CAASe,GAAG,CAACL,IAAAA,EAAMqB,YAAAA,CAAAA;AACvB;AAEA;;IAGO,SAASC,gBAAAA,CAAiBP,QAA0C,EAAA;IACvE,KAAK,MAAM,CAACf,IAAAA,EAAMqB,YAAAA,CAAa,IAAIL,MAAAA,CAAOC,OAAO,CAACF,QAAAA,CAAAA,CAAW;AACzDK,QAAAA,eAAAA,CAAgBpB,IAAAA,EAAMqB,YAAAA,CAAAA;AAC1B,IAAA;AACJ;AAEA;;IAGO,SAASE,cAAAA,CAAevB,IAAY,EAAA;IACvC,OAAOV,QAAAA,CAASc,GAAG,CAACJ,IAAAA,CAAAA;AACxB;AAEA;;;;;;AAMC,IACM,SAASwB,oBAAAA,GAAAA;IACZ,OAAO;AAAI,QAAA,GAAA,IAAI/B,GAAAA,CAAI;AAAIL,YAAAA,GAAAA,OAAAA,CAAQqC,IAAI,EAAA;AAAOlC,YAAAA,GAAAA,eAAAA,CAAgBkC,IAAI;AAAG,SAAA;AAAE,KAAA,CAACC,IAAI,EAAA;AAC5E;AAEA;;AAEC,IACM,SAASC,sBAAAA,GAAAA;IACZ,OAAO;AAAIrC,QAAAA,GAAAA,QAAAA,CAASmC,IAAI;AAAG,KAAA,CAACC,IAAI,EAAA;AACpC;AAEA;;;;;;AAMC,IACM,SAASE,aAAAA,GAAAA;AACZxC,IAAAA,OAAAA,CAAQyC,KAAK,EAAA;AACbvC,IAAAA,QAAAA,CAASuC,KAAK,EAAA;AACdtC,IAAAA,eAAAA,CAAgBsC,KAAK,EAAA;AACrBnC,IAAAA,mBAAAA,EAAAA;AACJ;;"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=when_registering_query_identities.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"when_registering_query_identities.d.ts","sourceRoot":"","sources":["../../../../bindings/for_bindingRegistry/when_registering_query_identities.ts"],"names":[],"mappings":""}