@cratis/arc 22.13.1 → 22.14.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (143) hide show
  1. package/README.md +5 -4
  2. package/dist/cjs/Globals.js.map +1 -1
  3. package/dist/cjs/UrlHelpers.js.map +1 -1
  4. package/dist/cjs/commands/Command.js.map +1 -1
  5. package/dist/cjs/commands/CommandResult.js.map +1 -1
  6. package/dist/cjs/commands/CommandResults.js.map +1 -1
  7. package/dist/cjs/commands/CommandValidator.js.map +1 -1
  8. package/dist/cjs/commands/index.js.map +1 -1
  9. package/dist/cjs/deepEqual.js.map +1 -1
  10. package/dist/cjs/identity/IIdentityProvider.js.map +1 -1
  11. package/dist/cjs/identity/IdentityProvider.js.map +1 -1
  12. package/dist/cjs/identity/index.js.map +1 -1
  13. package/dist/cjs/joinPaths.js.map +1 -1
  14. package/dist/cjs/messaging/IMessenger.js.map +1 -1
  15. package/dist/cjs/messaging/Message.js.map +1 -1
  16. package/dist/cjs/messaging/Messenger.js.map +1 -1
  17. package/dist/cjs/messaging/index.js.map +1 -1
  18. package/dist/cjs/queries/HubConnectionKeepAlive.js.map +1 -1
  19. package/dist/cjs/queries/IQueryProvider.js.map +1 -1
  20. package/dist/cjs/queries/NullObservableQueryConnection.js.map +1 -1
  21. package/dist/cjs/queries/ObservableQueryConnection.js.map +1 -1
  22. package/dist/cjs/queries/ObservableQueryConnectionFactory.js.map +1 -1
  23. package/dist/cjs/queries/ObservableQueryConnectionPool.js.map +1 -1
  24. package/dist/cjs/queries/ObservableQueryDiagnostics.js.map +1 -1
  25. package/dist/cjs/queries/ObservableQueryFor.js.map +1 -1
  26. package/dist/cjs/queries/ObservableQueryMultiplexer.js.map +1 -1
  27. package/dist/cjs/queries/ObservableQuerySubscription.js.map +1 -1
  28. package/dist/cjs/queries/Paging.js.map +1 -1
  29. package/dist/cjs/queries/PagingInfo.js.map +1 -1
  30. package/dist/cjs/queries/QueryFor.js.map +1 -1
  31. package/dist/cjs/queries/QueryHttpMethod.js.map +1 -1
  32. package/dist/cjs/queries/QueryHttpMethodResolver.js.map +1 -1
  33. package/dist/cjs/queries/QueryHttpRequest.js.map +1 -1
  34. package/dist/cjs/queries/QueryInstanceCache.js.map +1 -1
  35. package/dist/cjs/queries/QueryProvider.js.map +1 -1
  36. package/dist/cjs/queries/QueryResult.js.map +1 -1
  37. package/dist/cjs/queries/QueryResultWithState.js.map +1 -1
  38. package/dist/cjs/queries/QueryTransportMethod.js.map +1 -1
  39. package/dist/cjs/queries/QueryValidator.js.map +1 -1
  40. package/dist/cjs/queries/ReconnectPolicy.js.map +1 -1
  41. package/dist/cjs/queries/ServerSentEventHubConnection.js.map +1 -1
  42. package/dist/cjs/queries/ServerSentEventQueryConnection.js.map +1 -1
  43. package/dist/cjs/queries/SortDirection.js.map +1 -1
  44. package/dist/cjs/queries/Sorting.js.map +1 -1
  45. package/dist/cjs/queries/SortingActions.js.map +1 -1
  46. package/dist/cjs/queries/SortingActionsForObservableQuery.js.map +1 -1
  47. package/dist/cjs/queries/SortingActionsForQuery.js.map +1 -1
  48. package/dist/cjs/queries/ValidateRequestArguments.js.map +1 -1
  49. package/dist/cjs/queries/WebSocketHubConnection.js.map +1 -1
  50. package/dist/cjs/queries/WebSocketMessage.js.map +1 -1
  51. package/dist/cjs/queries/deserializeQueryModel.js.map +1 -1
  52. package/dist/cjs/queries/index.js.map +1 -1
  53. package/dist/cjs/queries/isAbortError.js.map +1 -1
  54. package/dist/cjs/queries/reconcileQueryData.js.map +1 -1
  55. package/dist/cjs/reflection/ParameterDescriptor.js.map +1 -1
  56. package/dist/cjs/reflection/ParametersHelper.js.map +1 -1
  57. package/dist/cjs/reflection/PropertyDescriptor.js.map +1 -1
  58. package/dist/cjs/reflection/index.js.map +1 -1
  59. package/dist/cjs/validation/PropertyRule.js.map +1 -1
  60. package/dist/cjs/validation/PropertyValidator.js.map +1 -1
  61. package/dist/cjs/validation/RuleBuilder.js.map +1 -1
  62. package/dist/cjs/validation/RuleBuilderExtensions.js.map +1 -1
  63. package/dist/cjs/validation/ValidationResult.js.map +1 -1
  64. package/dist/cjs/validation/ValidationResultReason.js.map +1 -1
  65. package/dist/cjs/validation/ValidationResultSeverity.js.map +1 -1
  66. package/dist/cjs/validation/Validator.js.map +1 -1
  67. package/dist/cjs/validation/index.js.map +1 -1
  68. package/dist/cjs/validation/rules/ComparisonRules.js.map +1 -1
  69. package/dist/cjs/validation/rules/EmailRule.js.map +1 -1
  70. package/dist/cjs/validation/rules/LengthRules.js.map +1 -1
  71. package/dist/cjs/validation/rules/NotEmptyRule.js.map +1 -1
  72. package/dist/cjs/validation/rules/PhoneRule.js.map +1 -1
  73. package/dist/cjs/validation/rules/RegexRule.js.map +1 -1
  74. package/dist/cjs/validation/rules/UrlRule.js.map +1 -1
  75. package/dist/esm/Globals.js.map +1 -1
  76. package/dist/esm/UrlHelpers.js.map +1 -1
  77. package/dist/esm/commands/Command.js.map +1 -1
  78. package/dist/esm/commands/CommandResult.js.map +1 -1
  79. package/dist/esm/commands/CommandResults.js.map +1 -1
  80. package/dist/esm/commands/CommandValidator.js.map +1 -1
  81. package/dist/esm/deepEqual.js.map +1 -1
  82. package/dist/esm/identity/IIdentityProvider.js.map +1 -1
  83. package/dist/esm/identity/IdentityProvider.js.map +1 -1
  84. package/dist/esm/joinPaths.js.map +1 -1
  85. package/dist/esm/messaging/IMessenger.js.map +1 -1
  86. package/dist/esm/messaging/Message.js.map +1 -1
  87. package/dist/esm/messaging/Messenger.js.map +1 -1
  88. package/dist/esm/queries/HubConnectionKeepAlive.js.map +1 -1
  89. package/dist/esm/queries/IQueryProvider.js.map +1 -1
  90. package/dist/esm/queries/NullObservableQueryConnection.js.map +1 -1
  91. package/dist/esm/queries/ObservableQueryConnection.js.map +1 -1
  92. package/dist/esm/queries/ObservableQueryConnectionFactory.js.map +1 -1
  93. package/dist/esm/queries/ObservableQueryConnectionPool.js.map +1 -1
  94. package/dist/esm/queries/ObservableQueryDiagnostics.js.map +1 -1
  95. package/dist/esm/queries/ObservableQueryFor.js.map +1 -1
  96. package/dist/esm/queries/ObservableQueryMultiplexer.js.map +1 -1
  97. package/dist/esm/queries/ObservableQuerySubscription.js.map +1 -1
  98. package/dist/esm/queries/Paging.js.map +1 -1
  99. package/dist/esm/queries/PagingInfo.js.map +1 -1
  100. package/dist/esm/queries/QueryFor.js.map +1 -1
  101. package/dist/esm/queries/QueryHttpMethod.js.map +1 -1
  102. package/dist/esm/queries/QueryHttpMethodResolver.js.map +1 -1
  103. package/dist/esm/queries/QueryHttpRequest.js.map +1 -1
  104. package/dist/esm/queries/QueryInstanceCache.js.map +1 -1
  105. package/dist/esm/queries/QueryProvider.js.map +1 -1
  106. package/dist/esm/queries/QueryResult.js.map +1 -1
  107. package/dist/esm/queries/QueryResultWithState.js.map +1 -1
  108. package/dist/esm/queries/QueryTransportMethod.js.map +1 -1
  109. package/dist/esm/queries/QueryValidator.js.map +1 -1
  110. package/dist/esm/queries/ReconnectPolicy.js.map +1 -1
  111. package/dist/esm/queries/ServerSentEventHubConnection.js.map +1 -1
  112. package/dist/esm/queries/ServerSentEventQueryConnection.js.map +1 -1
  113. package/dist/esm/queries/SortDirection.js.map +1 -1
  114. package/dist/esm/queries/Sorting.js.map +1 -1
  115. package/dist/esm/queries/SortingActions.js.map +1 -1
  116. package/dist/esm/queries/SortingActionsForObservableQuery.js.map +1 -1
  117. package/dist/esm/queries/SortingActionsForQuery.js.map +1 -1
  118. package/dist/esm/queries/ValidateRequestArguments.js.map +1 -1
  119. package/dist/esm/queries/WebSocketHubConnection.js.map +1 -1
  120. package/dist/esm/queries/WebSocketMessage.js.map +1 -1
  121. package/dist/esm/queries/deserializeQueryModel.js.map +1 -1
  122. package/dist/esm/queries/isAbortError.js.map +1 -1
  123. package/dist/esm/queries/reconcileQueryData.js.map +1 -1
  124. package/dist/esm/reflection/ParameterDescriptor.js.map +1 -1
  125. package/dist/esm/reflection/ParametersHelper.js.map +1 -1
  126. package/dist/esm/reflection/PropertyDescriptor.js.map +1 -1
  127. package/dist/esm/tsconfig.tsbuildinfo +1 -1
  128. package/dist/esm/validation/PropertyRule.js.map +1 -1
  129. package/dist/esm/validation/PropertyValidator.js.map +1 -1
  130. package/dist/esm/validation/RuleBuilder.js.map +1 -1
  131. package/dist/esm/validation/RuleBuilderExtensions.js.map +1 -1
  132. package/dist/esm/validation/ValidationResult.js.map +1 -1
  133. package/dist/esm/validation/ValidationResultReason.js.map +1 -1
  134. package/dist/esm/validation/ValidationResultSeverity.js.map +1 -1
  135. package/dist/esm/validation/Validator.js.map +1 -1
  136. package/dist/esm/validation/rules/ComparisonRules.js.map +1 -1
  137. package/dist/esm/validation/rules/EmailRule.js.map +1 -1
  138. package/dist/esm/validation/rules/LengthRules.js.map +1 -1
  139. package/dist/esm/validation/rules/NotEmptyRule.js.map +1 -1
  140. package/dist/esm/validation/rules/PhoneRule.js.map +1 -1
  141. package/dist/esm/validation/rules/RegexRule.js.map +1 -1
  142. package/dist/esm/validation/rules/UrlRule.js.map +1 -1
  143. package/package.json +3 -3
@@ -1 +1 @@
1
- {"version":3,"file":"SortingActionsForQuery.js","sources":["../../../queries/SortingActionsForQuery.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 { IQueryFor } from './IQueryFor';\nimport { SortDirection } from './SortDirection';\nimport { Sorting } from './Sorting';\n\n/**\n * Represents sorting for a query.\n */\nexport class SortingActionsForQuery<TDataType, TArguments = object> {\n\n /**\n * Initializes a new instance of {@link SortingActionsForQuery}.\n * @param {string} field The field that the sorting represents.\n * @param {IQueryFor<TDataType, TArguments>} query The query that holds the field.\n */\n constructor(readonly field: string, readonly query: IQueryFor<TDataType, TArguments>) { \n }\n\n /**\n * Instructs query to sort ascending for the field.\n */\n ascending(): Sorting {\n this.query.sorting = new Sorting(this.field, SortDirection.ascending);\n return this.query.sorting;\n }\n\n /**\n * Instructs query to sort ascending for the field.\n */\n descending(): Sorting {\n this.query.sorting = new Sorting(this.field, SortDirection.descending);\n return this.query.sorting;\n }\n}\n"],"names":["SortingActionsForQuery","query","field","ascending","sorting","Sorting","SortDirection","descending"],"mappings":";;;AAAA;AACA;AAMA;;AAEC,IACM,MAAMA,sBAAAA,CAAAA;;;AAET;;;;AAIC,QACD,YAAY,KAAsB,EAAWC,KAAuC,CAAE;aAAjEC,KAAAA,GAAAA,KAAAA;aAAwBD,KAAAA,GAAAA,KAAAA;AAC7C,IAAA;AAEA;;AAEE,SACFE,SAAAA,GAAqB;AACjB,QAAA,IAAI,CAACF,KAAK,CAACG,OAAO,GAAG,IAAIC,OAAAA,CAAQ,IAAI,CAACH,KAAK,EAAEI,aAAAA,CAAcH,SAAS,CAAA;AACpE,QAAA,OAAO,IAAI,CAACF,KAAK,CAACG,OAAO;AAC7B,IAAA;AAEA;;AAEE,SACFG,UAAAA,GAAsB;AAClB,QAAA,IAAI,CAACN,KAAK,CAACG,OAAO,GAAG,IAAIC,OAAAA,CAAQ,IAAI,CAACH,KAAK,EAAEI,aAAAA,CAAcC,UAAU,CAAA;AACrE,QAAA,OAAO,IAAI,CAACN,KAAK,CAACG,OAAO;AAC7B,IAAA;AACJ;;;;"}
1
+ {"version":3,"file":"SortingActionsForQuery.js","sources":["../../../queries/SortingActionsForQuery.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 { IQueryFor } from './IQueryFor';\nimport { SortDirection } from './SortDirection';\nimport { Sorting } from './Sorting';\n\n/**\n * Represents sorting for a query.\n */\nexport class SortingActionsForQuery<TDataType, TArguments = object> {\n\n /**\n * Initializes a new instance of {@link SortingActionsForQuery}.\n * @param {string} field The field that the sorting represents.\n * @param {IQueryFor<TDataType, TArguments>} query The query that holds the field.\n */\n constructor(readonly field: string, readonly query: IQueryFor<TDataType, TArguments>) { \n }\n\n /**\n * Instructs query to sort ascending for the field.\n */\n ascending(): Sorting {\n this.query.sorting = new Sorting(this.field, SortDirection.ascending);\n return this.query.sorting;\n }\n\n /**\n * Instructs query to sort ascending for the field.\n */\n descending(): Sorting {\n this.query.sorting = new Sorting(this.field, SortDirection.descending);\n return this.query.sorting;\n }\n}\n"],"names":["SortingActionsForQuery","query","field","ascending","sorting","Sorting","SortDirection","descending"],"mappings":";;;AAAA;AACA;AAMA;;AAEC,IACM,MAAMA,sBAAAA,CAAAA;;;AAET;;;;AAIC,QACD,YAAY,KAAsB,EAAWC,KAAuC,CAAE;aAAjEC,KAAAA,GAAAA,KAAAA;aAAwBD,KAAAA,GAAAA,KAAAA;AAC7C,IAAA;AAEA;;AAEE,SACFE,SAAAA,GAAqB;AACjB,QAAA,IAAI,CAACF,KAAK,CAACG,OAAO,GAAG,IAAIC,OAAAA,CAAQ,IAAI,CAACH,KAAK,EAAEI,aAAAA,CAAcH,SAAS,CAAA;AACpE,QAAA,OAAO,IAAI,CAACF,KAAK,CAACG,OAAO;AAC7B,IAAA;AAEA;;AAEE,SACFG,UAAAA,GAAsB;AAClB,QAAA,IAAI,CAACN,KAAK,CAACG,OAAO,GAAG,IAAIC,OAAAA,CAAQ,IAAI,CAACH,KAAK,EAAEI,aAAAA,CAAcC,UAAU,CAAA;AACrE,QAAA,OAAO,IAAI,CAACN,KAAK,CAACG,OAAO;AAC7B,IAAA;AACJ;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"ValidateRequestArguments.js","sources":["../../../queries/ValidateRequestArguments.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\n/**\n * Validate request arguments.\n * @param {string} requestName Name of request.\n * @param {string[]} expectedRequestArguments Array of all expected arguments.\n * @param {*} actualArguments Object containing the arguments.\n * @returns True if valid, false if not.\n*/\nexport function ValidateRequestArguments(requestName: string, expectedRequestArguments: string[], actualArguments?: object): boolean {\n if (expectedRequestArguments.length > 0) {\n const missing: string[] = [];\n\n if (!actualArguments) {\n expectedRequestArguments.forEach(_ => missing.push(_));\n } else {\n for (const argument of expectedRequestArguments) {\n if (!actualArguments.hasOwnProperty(argument) ||\n actualArguments[argument] === undefined ||\n actualArguments[argument] === null ||\n actualArguments[argument] === '') {\n missing.push(argument);\n }\n }\n }\n\n if (missing.length > 0) {\n const missingArgumentsString = missing.join(', ');\n console.log(`Warning: Missing (${missingArgumentsString}) arguments for request (${requestName}). Will not perform.`);\n return false;\n }\n }\n\n return true;\n}\n"],"names":["ValidateRequestArguments","requestName","expectedRequestArguments","actualArguments","length","missing","forEach","_","push","argument","hasOwnProperty","undefined","missingArgumentsString","join","console","log"],"mappings":"AAAA;AACA;AAEA;;;;;;AAMA,GACO,SAASA,wBAAAA,CAAyBC,WAAmB,EAAEC,wBAAkC,EAAEC,eAAwB,EAAA;IACtH,IAAID,wBAAAA,CAAyBE,MAAM,GAAG,CAAA,EAAG;AACrC,QAAA,MAAMC,UAAoB,EAAE;AAE5B,QAAA,IAAI,CAACF,eAAAA,EAAiB;AAClBD,YAAAA,wBAAAA,CAAyBI,OAAO,CAACC,CAAAA,CAAAA,GAAKF,OAAAA,CAAQG,IAAI,CAACD,CAAAA,CAAAA,CAAAA;QACvD,CAAA,MAAO;YACH,KAAK,MAAME,YAAYP,wBAAAA,CAA0B;AAC7C,gBAAA,IAAI,CAACC,eAAAA,CAAgBO,cAAc,CAACD,QAAAA,CAAAA,IAChCN,eAAe,CAACM,QAAAA,CAAS,KAAKE,aAC9BR,eAAe,CAACM,SAAS,KAAK,IAAA,IAC9BN,eAAe,CAACM,QAAAA,CAAS,KAAK,EAAA,EAAI;AAClCJ,oBAAAA,OAAAA,CAAQG,IAAI,CAACC,QAAAA,CAAAA;AACjB,gBAAA;AACJ,YAAA;AACJ,QAAA;QAEA,IAAIJ,OAAAA,CAAQD,MAAM,GAAG,CAAA,EAAG;YACpB,MAAMQ,sBAAAA,GAAyBP,OAAAA,CAAQQ,IAAI,CAAC,IAAA,CAAA;YAC5CC,OAAAA,CAAQC,GAAG,CAAC,CAAC,kBAAkB,EAAEH,uBAAuB,yBAAyB,EAAEX,WAAAA,CAAY,oBAAoB,CAAC,CAAA;YACpH,OAAO,KAAA;AACX,QAAA;AACJ,IAAA;IAEA,OAAO,IAAA;AACX;;;;"}
1
+ {"version":3,"file":"ValidateRequestArguments.js","sources":["../../../queries/ValidateRequestArguments.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\n/**\n * Validate request arguments.\n * @param {string} requestName Name of request.\n * @param {string[]} expectedRequestArguments Array of all expected arguments.\n * @param {*} actualArguments Object containing the arguments.\n * @returns True if valid, false if not.\n*/\nexport function ValidateRequestArguments(requestName: string, expectedRequestArguments: string[], actualArguments?: object): boolean {\n if (expectedRequestArguments.length > 0) {\n const missing: string[] = [];\n\n if (!actualArguments) {\n expectedRequestArguments.forEach(_ => missing.push(_));\n } else {\n for (const argument of expectedRequestArguments) {\n if (!actualArguments.hasOwnProperty(argument) ||\n actualArguments[argument] === undefined ||\n actualArguments[argument] === null ||\n actualArguments[argument] === '') {\n missing.push(argument);\n }\n }\n }\n\n if (missing.length > 0) {\n const missingArgumentsString = missing.join(', ');\n console.log(`Warning: Missing (${missingArgumentsString}) arguments for request (${requestName}). Will not perform.`);\n return false;\n }\n }\n\n return true;\n}\n"],"names":["ValidateRequestArguments","requestName","expectedRequestArguments","actualArguments","length","missing","forEach","_","push","argument","hasOwnProperty","undefined","missingArgumentsString","join","console","log"],"mappings":"AAAA;AACA;AAEA;;;;;;AAMA,GACO,SAASA,wBAAAA,CAAyBC,WAAmB,EAAEC,wBAAkC,EAAEC,eAAwB,EAAA;IACtH,IAAID,wBAAAA,CAAyBE,MAAM,GAAG,CAAA,EAAG;AACrC,QAAA,MAAMC,UAAoB,EAAE;AAE5B,QAAA,IAAI,CAACF,eAAAA,EAAiB;AAClBD,YAAAA,wBAAAA,CAAyBI,OAAO,CAACC,CAAAA,CAAAA,GAAKF,OAAAA,CAAQG,IAAI,CAACD,CAAAA,CAAAA,CAAAA;QACvD,CAAA,MAAO;YACH,KAAK,MAAME,YAAYP,wBAAAA,CAA0B;AAC7C,gBAAA,IAAI,CAACC,eAAAA,CAAgBO,cAAc,CAACD,QAAAA,CAAAA,IAChCN,eAAe,CAACM,QAAAA,CAAS,KAAKE,aAC9BR,eAAe,CAACM,SAAS,KAAK,IAAA,IAC9BN,eAAe,CAACM,QAAAA,CAAS,KAAK,EAAA,EAAI;AAClCJ,oBAAAA,OAAAA,CAAQG,IAAI,CAACC,QAAAA,CAAAA;AACjB,gBAAA;AACJ,YAAA;AACJ,QAAA;QAEA,IAAIJ,OAAAA,CAAQD,MAAM,GAAG,CAAA,EAAG;YACpB,MAAMQ,sBAAAA,GAAyBP,OAAAA,CAAQQ,IAAI,CAAC,IAAA,CAAA;YAC5CC,OAAAA,CAAQC,GAAG,CAAC,CAAC,kBAAkB,EAAEH,uBAAuB,yBAAyB,EAAEX,WAAAA,CAAY,oBAAoB,CAAC,CAAA;YACpH,OAAO,KAAA;AACX,QAAA;AACJ,IAAA;IAEA,OAAO,IAAA;AACX;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"WebSocketHubConnection.js","sources":["../../../queries/WebSocketHubConnection.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 { Globals } from '../Globals';\nimport type { DataReceived } from './ObservableQueryConnection';\nimport { HubConnectionKeepAlive } from './HubConnectionKeepAlive';\nimport type { IReconnectPolicy } from './IReconnectPolicy';\nimport { ReconnectPolicy } from './ReconnectPolicy';\nimport { QueryResult } from './QueryResult';\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\n/**\n * Message types matching the backend {@link ObservableQueryHubMessageType} enum.\n * Serialized as strings by the JsonStringEnumConverter on the server.\n */\nexport enum HubMessageType {\n Subscribe = 'Subscribe',\n Unsubscribe = 'Unsubscribe',\n QueryResult = 'QueryResult',\n Unauthorized = 'Unauthorized',\n Error = 'Error',\n Ping = 'Ping',\n Pong = 'Pong',\n Connected = 'Connected',\n}\n\n/**\n * Wire format for messages exchanged over the observable query WebSocket and SSE hub transports.\n */\nexport interface HubMessage {\n type: HubMessageType;\n queryId?: string;\n\n /** Optional positive safe-integer revision used to reject stale replacement messages. */\n revision?: number;\n\n /**\n * Whether the server supports revision-aware subscription operations and result frames.\n * Only present on {@link HubMessageType.Connected} messages from capable servers.\n */\n supportsSubscriptionRevisions?: boolean;\n payload?: any;\n timestamp?: number;\n\n /**\n * The server's keep-alive interval in milliseconds, or 0 when keep-alive is disabled.\n * Only present on {@link HubMessageType.Connected} messages.\n */\n keepAliveIntervalMs?: number;\n}\n\n/**\n * Matches the backend {@link ObservableQuerySubscriptionRequest} record.\n */\nexport interface SubscriptionRequest {\n queryName: string;\n arguments?: Record<string, string | null>;\n page?: number;\n pageSize?: number;\n sortBy?: string;\n sortDirection?: string;\n transferMode?: string;\n}\n\ninterface ActiveSubscription {\n request: SubscriptionRequest;\n callback: DataReceived<any>;\n revision: number;\n}\n\n/**\n * Represents a single multiplexed WebSocket connection to the observable query hub\n * at {@code /.cratis/queries/ws}.\n *\n * Multiple query subscriptions are carried over the same physical WebSocket. Each subscription\n * is identified by a client-generated {@code queryId}; the server tags every result message with\n * the same id so responses can be routed to the correct callback. The client initially subscribes\n * without revisions for compatibility with older servers, then replaces active subscriptions with\n * revision-aware operations when the server advertises support in a Connected message.\n */\nexport class WebSocketHubConnection {\n private _socket?: WebSocket;\n private _disconnected = false;\n private _subscriptions: Map<string, ActiveSubscription> = new Map();\n private readonly _keepAlive: HubConnectionKeepAlive;\n private _lastPingSentTime?: number;\n private _lastPongLatency: number = 0;\n private _latencySamples: number[] = [];\n private _nextRevision = 0;\n private _supportsSubscriptionRevisions = false;\n private _reconnectPending = false;\n\n /**\n * Initializes a new instance of {@link WebSocketHubConnection}.\n * @param {string} _url The WebSocket URL of the hub endpoint (e.g. {@code ws://localhost:5000/.cratis/queries/ws}).\n * @param {string} _microservice The microservice name to pass as a query argument.\n * @param {number} pingIntervalMs How often to send keep-alive pings when the connection is idle (default: 10 000 ms).\n * @param {IReconnectPolicy} _policy The reconnect policy to use (default: {@link ReconnectPolicy}).\n */\n constructor(\n private readonly _url: string,\n private readonly _microservice: string,\n pingIntervalMs: number = 10000,\n private readonly _policy: IReconnectPolicy = new ReconnectPolicy(),\n ) {\n this._keepAlive = new HubConnectionKeepAlive(pingIntervalMs, () => {\n if (this._socket?.readyState === WebSocket.OPEN) {\n this._lastPingSentTime = Date.now();\n this.sendMessage({\n type: HubMessageType.Ping,\n timestamp: this._lastPingSentTime,\n });\n }\n });\n }\n\n /**\n * Gets the number of active query subscriptions on this connection.\n */\n get queryCount(): number {\n return this._subscriptions.size;\n }\n\n /**\n * Gets whether the WebSocket connection is currently open.\n */\n get isConnected(): boolean {\n return this._socket?.readyState === WebSocket.OPEN;\n }\n\n /**\n * Gets the latency of the last ping/pong sequence in milliseconds.\n */\n get lastPingLatency(): number {\n return this._lastPongLatency;\n }\n\n /**\n * Gets the rolling average latency in milliseconds.\n */\n get averageLatency(): number {\n if (this._latencySamples.length === 0) return 0;\n return (\n this._latencySamples.reduce((a, b) => a + b, 0) / this._latencySamples.length\n );\n }\n\n /**\n * Subscribe to a query on this hub connection.\n * If the WebSocket is not yet open, the subscribe message will be sent once the connection is established.\n * @param {string} queryId Client-generated unique identifier for this subscription.\n * @param {SubscriptionRequest} request The subscription request payload.\n * @param {DataReceived<any>} callback Callback invoked whenever the server pushes a result for this query.\n */\n subscribe(\n queryId: string,\n request: SubscriptionRequest,\n callback: DataReceived<any>,\n ): void {\n const subscription = { request, callback, revision: this.getNextRevision() };\n this._subscriptions.set(queryId, subscription);\n this.ensureConnected();\n\n if (this._socket?.readyState === WebSocket.OPEN) {\n this.sendSubscribeMessage(queryId, subscription);\n }\n // If not yet open, sendAllSubscriptions will fire in onopen.\n }\n\n /**\n * Unsubscribe from a query on this hub connection.\n * @param {string} queryId The identifier of the subscription to cancel.\n */\n unsubscribe(queryId: string): void {\n const subscription = this._subscriptions.get(queryId);\n this._subscriptions.delete(queryId);\n\n if (this._socket?.readyState === WebSocket.OPEN && subscription) {\n const message: HubMessage = {\n type: HubMessageType.Unsubscribe,\n queryId,\n };\n if (this._supportsSubscriptionRevisions) {\n message.revision = subscription.revision;\n }\n this.sendMessage(message);\n }\n\n // If no subscriptions remain, close the connection to free resources.\n if (this._subscriptions.size === 0) {\n this.close();\n }\n }\n\n /**\n * Permanently close this hub connection and clean up all subscriptions.\n */\n dispose(): void {\n this._subscriptions.clear();\n this.close();\n }\n\n private ensureConnected(): void {\n if (this._disconnected) {\n // Reset disconnected flag when a new subscription comes in\n this._disconnected = false;\n }\n\n if (\n this._socket &&\n (this._socket.readyState === WebSocket.OPEN ||\n this._socket.readyState === WebSocket.CONNECTING)\n ) {\n this.cancelPendingReconnect();\n return;\n }\n\n // A subscription can arrive while an earlier close is waiting in reconnect backoff. The immediate open owns\n // the connection now, so the delayed callback must not be allowed to create a competing socket later.\n this.cancelPendingReconnect();\n this.openSocket();\n }\n\n private close(): void {\n this._disconnected = true;\n this._keepAlive.stop();\n this._policy.cancel();\n this._reconnectPending = false;\n const socket = this._socket;\n this._socket = undefined;\n this._supportsSubscriptionRevisions = false;\n if (socket) {\n this.detachAndCloseSocket(socket);\n }\n }\n\n private openSocket(): void {\n const currentSocket = this._socket;\n if (\n currentSocket &&\n (currentSocket.readyState === WebSocket.OPEN ||\n currentSocket.readyState === WebSocket.CONNECTING)\n ) {\n return;\n }\n\n if (currentSocket) {\n this._socket = undefined;\n this.detachAndCloseSocket(currentSocket);\n }\n\n this._supportsSubscriptionRevisions = false;\n\n let url = this._url;\n if (this._microservice?.length > 0) {\n const param = `${Globals.microserviceWSQueryArgument}=${encodeURIComponent(this._microservice)}`;\n url += (url.includes('?') ? '&' : '?') + param;\n }\n\n const socket = new WebSocket(url);\n this._socket = socket;\n\n socket.onopen = () => {\n if (this._socket !== socket || this._disconnected) return;\n console.log('Hub connection established', url);\n this.cancelPendingReconnect();\n this._policy.reset();\n this._keepAlive.start();\n this.sendAllSubscriptions();\n };\n\n socket.onclose = () => {\n if (this._socket !== socket || this._disconnected) return;\n console.log('Hub connection closed', url);\n this._socket = undefined;\n this._supportsSubscriptionRevisions = false;\n this._keepAlive.stop();\n if (this._subscriptions.size === 0) return;\n this._reconnectPending = true;\n const scheduled = this._policy.schedule(() => {\n this._reconnectPending = false;\n if (!this._disconnected && this._subscriptions.size > 0) {\n this.ensureConnected();\n }\n }, this._url);\n if (!scheduled) {\n this._reconnectPending = false;\n }\n };\n\n socket.onerror = (error) => {\n if (this._socket !== socket || this._disconnected) return;\n console.error('Hub connection error', url, error);\n this._keepAlive.stop();\n // onclose will fire after onerror, triggering reconnect\n };\n\n socket.onmessage = (ev) => {\n if (this._socket !== socket || this._disconnected) return;\n this.handleMessage(ev.data as string);\n };\n }\n\n private cancelPendingReconnect(): void {\n if (!this._reconnectPending) return;\n\n this._policy.cancel();\n this._reconnectPending = false;\n }\n\n private detachAndCloseSocket(socket: WebSocket): void {\n socket.onopen = null;\n socket.onclose = null;\n socket.onerror = null;\n socket.onmessage = null;\n socket.close();\n }\n\n private sendAllSubscriptions(): void {\n for (const [queryId, sub] of this._subscriptions) {\n this.sendSubscribeMessage(queryId, sub);\n }\n }\n\n private sendSubscribeMessage(\n queryId: string,\n subscription: ActiveSubscription,\n ): void {\n const message: HubMessage = {\n type: HubMessageType.Subscribe,\n queryId,\n payload: subscription.request,\n };\n if (this._supportsSubscriptionRevisions) {\n message.revision = subscription.revision;\n }\n this.sendMessage(message);\n }\n\n private sendMessage(message: HubMessage): void {\n if (this._socket?.readyState === WebSocket.OPEN) {\n this._socket.send(JSON.stringify(message));\n }\n }\n\n private handleMessage(rawData: string): void {\n try {\n const message = JSON.parse(rawData) as HubMessage;\n\n // Every received message is activity — skip keep-alive ping if data is flowing.\n this._keepAlive.recordActivity();\n\n switch (message.type) {\n case HubMessageType.Connected:\n this.handleConnected(message);\n break;\n case HubMessageType.QueryResult:\n this.handleQueryResult(message);\n break;\n case HubMessageType.Pong:\n this.handlePong(message);\n break;\n case HubMessageType.Unauthorized:\n console.warn('Hub: query unauthorized', message.queryId);\n this.handleUnauthorized(message);\n break;\n case HubMessageType.Error:\n if (this.isMessageForCurrentSubscription(message)) {\n console.error(\n 'Hub: query error',\n message.queryId,\n message.payload,\n );\n }\n break;\n }\n } catch (error) {\n console.error('Hub: error parsing message', error);\n }\n }\n\n private handleConnected(message: HubMessage): void {\n if (\n message.supportsSubscriptionRevisions !== true ||\n this._supportsSubscriptionRevisions\n ) {\n return;\n }\n\n this._supportsSubscriptionRevisions = true;\n\n // The legacy subscriptions sent on socket open keep this client compatible with older servers.\n // Ordered WebSocket delivery means these revision-aware replacements are processed afterwards.\n this.sendAllSubscriptions();\n }\n\n private handleQueryResult(message: HubMessage): void {\n if (!message.queryId) return;\n\n const sub = this._subscriptions.get(message.queryId);\n if (!sub || !this.isMessageForCurrentSubscription(message)) return;\n\n const result = message.payload as QueryResult<any>;\n sub.callback(result);\n }\n\n private handleUnauthorized(message: HubMessage): void {\n if (!message.queryId) return;\n\n const sub = this._subscriptions.get(message.queryId);\n if (!sub || !this.isMessageForCurrentSubscription(message)) return;\n\n this._subscriptions.delete(message.queryId);\n sub.callback(QueryResult.unauthorized());\n }\n\n private isMessageForCurrentSubscription(message: HubMessage): boolean {\n if (!message.queryId) return false;\n\n if (!this._supportsSubscriptionRevisions) {\n return (\n message.revision === undefined &&\n this._subscriptions.has(message.queryId)\n );\n }\n\n return (\n this.isValidRevision(message.revision) &&\n this._subscriptions.get(message.queryId)?.revision === message.revision\n );\n }\n\n private isValidRevision(revision: number | undefined): revision is number {\n return revision !== undefined && Number.isSafeInteger(revision) && revision > 0;\n }\n\n private getNextRevision(): number {\n if (this._nextRevision >= Number.MAX_SAFE_INTEGER) {\n throw new RangeError(\n 'WebSocket hub subscription revision exhausted the safe integer range',\n );\n }\n\n return ++this._nextRevision;\n }\n\n private handlePong(message: HubMessage): void {\n if (message.timestamp && this._lastPingSentTime) {\n const latency = Date.now() - message.timestamp;\n this._lastPongLatency = latency;\n this._latencySamples.push(latency);\n\n if (this._latencySamples.length > 100) {\n this._latencySamples.shift();\n }\n }\n }\n}\n"],"names":["HubMessageType","WebSocketHubConnection","_socket","_disconnected","_subscriptions","Map","_keepAlive","_lastPingSentTime","_lastPongLatency","_latencySamples","_nextRevision","_supportsSubscriptionRevisions","_reconnectPending","_url","pingIntervalMs","_policy","ReconnectPolicy","_microservice","HubConnectionKeepAlive","readyState","WebSocket","OPEN","Date","now","sendMessage","type","timestamp","queryCount","size","isConnected","lastPingLatency","averageLatency","length","reduce","a","b","subscribe","queryId","request","callback","subscription","revision","getNextRevision","set","ensureConnected","sendSubscribeMessage","unsubscribe","get","delete","message","close","dispose","clear","CONNECTING","cancelPendingReconnect","openSocket","stop","cancel","socket","undefined","detachAndCloseSocket","currentSocket","url","param","Globals","microserviceWSQueryArgument","encodeURIComponent","includes","onopen","console","log","reset","start","sendAllSubscriptions","onclose","scheduled","schedule","onerror","error","onmessage","ev","handleMessage","data","sub","payload","send","JSON","stringify","rawData","parse","recordActivity","handleConnected","handleQueryResult","handlePong","warn","handleUnauthorized","isMessageForCurrentSubscription","supportsSubscriptionRevisions","result","QueryResult","unauthorized","has","isValidRevision","Number","isSafeInteger","MAX_SAFE_INTEGER","RangeError","latency","push","shift"],"mappings":"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"}
1
+ {"version":3,"file":"WebSocketHubConnection.js","sources":["../../../queries/WebSocketHubConnection.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 { Globals } from '../Globals';\nimport type { DataReceived } from './ObservableQueryConnection';\nimport { HubConnectionKeepAlive } from './HubConnectionKeepAlive';\nimport type { IReconnectPolicy } from './IReconnectPolicy';\nimport { ReconnectPolicy } from './ReconnectPolicy';\nimport { QueryResult } from './QueryResult';\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\n/**\n * Message types matching the backend {@link ObservableQueryHubMessageType} enum.\n * Serialized as strings by the JsonStringEnumConverter on the server.\n */\nexport enum HubMessageType {\n Subscribe = 'Subscribe',\n Unsubscribe = 'Unsubscribe',\n QueryResult = 'QueryResult',\n Unauthorized = 'Unauthorized',\n Error = 'Error',\n Ping = 'Ping',\n Pong = 'Pong',\n Connected = 'Connected',\n}\n\n/**\n * Wire format for messages exchanged over the observable query WebSocket and SSE hub transports.\n */\nexport interface HubMessage {\n type: HubMessageType;\n queryId?: string;\n\n /** Optional positive safe-integer revision used to reject stale replacement messages. */\n revision?: number;\n\n /**\n * Whether the server supports revision-aware subscription operations and result frames.\n * Only present on {@link HubMessageType.Connected} messages from capable servers.\n */\n supportsSubscriptionRevisions?: boolean;\n payload?: any;\n timestamp?: number;\n\n /**\n * The server's keep-alive interval in milliseconds, or 0 when keep-alive is disabled.\n * Only present on {@link HubMessageType.Connected} messages.\n */\n keepAliveIntervalMs?: number;\n}\n\n/**\n * Matches the backend {@link ObservableQuerySubscriptionRequest} record.\n */\nexport interface SubscriptionRequest {\n queryName: string;\n arguments?: Record<string, string | null>;\n page?: number;\n pageSize?: number;\n sortBy?: string;\n sortDirection?: string;\n transferMode?: string;\n}\n\ninterface ActiveSubscription {\n request: SubscriptionRequest;\n callback: DataReceived<any>;\n revision: number;\n}\n\n/**\n * Represents a single multiplexed WebSocket connection to the observable query hub\n * at {@code /.cratis/queries/ws}.\n *\n * Multiple query subscriptions are carried over the same physical WebSocket. Each subscription\n * is identified by a client-generated {@code queryId}; the server tags every result message with\n * the same id so responses can be routed to the correct callback. The client initially subscribes\n * without revisions for compatibility with older servers, then replaces active subscriptions with\n * revision-aware operations when the server advertises support in a Connected message.\n */\nexport class WebSocketHubConnection {\n private _socket?: WebSocket;\n private _disconnected = false;\n private _subscriptions: Map<string, ActiveSubscription> = new Map();\n private readonly _keepAlive: HubConnectionKeepAlive;\n private _lastPingSentTime?: number;\n private _lastPongLatency: number = 0;\n private _latencySamples: number[] = [];\n private _nextRevision = 0;\n private _supportsSubscriptionRevisions = false;\n private _reconnectPending = false;\n\n /**\n * Initializes a new instance of {@link WebSocketHubConnection}.\n * @param {string} _url The WebSocket URL of the hub endpoint (e.g. {@code ws://localhost:5000/.cratis/queries/ws}).\n * @param {string} _microservice The microservice name to pass as a query argument.\n * @param {number} pingIntervalMs How often to send keep-alive pings when the connection is idle (default: 10 000 ms).\n * @param {IReconnectPolicy} _policy The reconnect policy to use (default: {@link ReconnectPolicy}).\n */\n constructor(\n private readonly _url: string,\n private readonly _microservice: string,\n pingIntervalMs: number = 10000,\n private readonly _policy: IReconnectPolicy = new ReconnectPolicy(),\n ) {\n this._keepAlive = new HubConnectionKeepAlive(pingIntervalMs, () => {\n if (this._socket?.readyState === WebSocket.OPEN) {\n this._lastPingSentTime = Date.now();\n this.sendMessage({\n type: HubMessageType.Ping,\n timestamp: this._lastPingSentTime,\n });\n }\n });\n }\n\n /**\n * Gets the number of active query subscriptions on this connection.\n */\n get queryCount(): number {\n return this._subscriptions.size;\n }\n\n /**\n * Gets whether the WebSocket connection is currently open.\n */\n get isConnected(): boolean {\n return this._socket?.readyState === WebSocket.OPEN;\n }\n\n /**\n * Gets the latency of the last ping/pong sequence in milliseconds.\n */\n get lastPingLatency(): number {\n return this._lastPongLatency;\n }\n\n /**\n * Gets the rolling average latency in milliseconds.\n */\n get averageLatency(): number {\n if (this._latencySamples.length === 0) return 0;\n return (\n this._latencySamples.reduce((a, b) => a + b, 0) / this._latencySamples.length\n );\n }\n\n /**\n * Subscribe to a query on this hub connection.\n * If the WebSocket is not yet open, the subscribe message will be sent once the connection is established.\n * @param {string} queryId Client-generated unique identifier for this subscription.\n * @param {SubscriptionRequest} request The subscription request payload.\n * @param {DataReceived<any>} callback Callback invoked whenever the server pushes a result for this query.\n */\n subscribe(\n queryId: string,\n request: SubscriptionRequest,\n callback: DataReceived<any>,\n ): void {\n const subscription = { request, callback, revision: this.getNextRevision() };\n this._subscriptions.set(queryId, subscription);\n this.ensureConnected();\n\n if (this._socket?.readyState === WebSocket.OPEN) {\n this.sendSubscribeMessage(queryId, subscription);\n }\n // If not yet open, sendAllSubscriptions will fire in onopen.\n }\n\n /**\n * Unsubscribe from a query on this hub connection.\n * @param {string} queryId The identifier of the subscription to cancel.\n */\n unsubscribe(queryId: string): void {\n const subscription = this._subscriptions.get(queryId);\n this._subscriptions.delete(queryId);\n\n if (this._socket?.readyState === WebSocket.OPEN && subscription) {\n const message: HubMessage = {\n type: HubMessageType.Unsubscribe,\n queryId,\n };\n if (this._supportsSubscriptionRevisions) {\n message.revision = subscription.revision;\n }\n this.sendMessage(message);\n }\n\n // If no subscriptions remain, close the connection to free resources.\n if (this._subscriptions.size === 0) {\n this.close();\n }\n }\n\n /**\n * Permanently close this hub connection and clean up all subscriptions.\n */\n dispose(): void {\n this._subscriptions.clear();\n this.close();\n }\n\n private ensureConnected(): void {\n if (this._disconnected) {\n // Reset disconnected flag when a new subscription comes in\n this._disconnected = false;\n }\n\n if (\n this._socket &&\n (this._socket.readyState === WebSocket.OPEN ||\n this._socket.readyState === WebSocket.CONNECTING)\n ) {\n this.cancelPendingReconnect();\n return;\n }\n\n // A subscription can arrive while an earlier close is waiting in reconnect backoff. The immediate open owns\n // the connection now, so the delayed callback must not be allowed to create a competing socket later.\n this.cancelPendingReconnect();\n this.openSocket();\n }\n\n private close(): void {\n this._disconnected = true;\n this._keepAlive.stop();\n this._policy.cancel();\n this._reconnectPending = false;\n const socket = this._socket;\n this._socket = undefined;\n this._supportsSubscriptionRevisions = false;\n if (socket) {\n this.detachAndCloseSocket(socket);\n }\n }\n\n private openSocket(): void {\n const currentSocket = this._socket;\n if (\n currentSocket &&\n (currentSocket.readyState === WebSocket.OPEN ||\n currentSocket.readyState === WebSocket.CONNECTING)\n ) {\n return;\n }\n\n if (currentSocket) {\n this._socket = undefined;\n this.detachAndCloseSocket(currentSocket);\n }\n\n this._supportsSubscriptionRevisions = false;\n\n let url = this._url;\n if (this._microservice?.length > 0) {\n const param = `${Globals.microserviceWSQueryArgument}=${encodeURIComponent(this._microservice)}`;\n url += (url.includes('?') ? '&' : '?') + param;\n }\n\n const socket = new WebSocket(url);\n this._socket = socket;\n\n socket.onopen = () => {\n if (this._socket !== socket || this._disconnected) return;\n console.log('Hub connection established', url);\n this.cancelPendingReconnect();\n this._policy.reset();\n this._keepAlive.start();\n this.sendAllSubscriptions();\n };\n\n socket.onclose = () => {\n if (this._socket !== socket || this._disconnected) return;\n console.log('Hub connection closed', url);\n this._socket = undefined;\n this._supportsSubscriptionRevisions = false;\n this._keepAlive.stop();\n if (this._subscriptions.size === 0) return;\n this._reconnectPending = true;\n const scheduled = this._policy.schedule(() => {\n this._reconnectPending = false;\n if (!this._disconnected && this._subscriptions.size > 0) {\n this.ensureConnected();\n }\n }, this._url);\n if (!scheduled) {\n this._reconnectPending = false;\n }\n };\n\n socket.onerror = (error) => {\n if (this._socket !== socket || this._disconnected) return;\n console.error('Hub connection error', url, error);\n this._keepAlive.stop();\n // onclose will fire after onerror, triggering reconnect\n };\n\n socket.onmessage = (ev) => {\n if (this._socket !== socket || this._disconnected) return;\n this.handleMessage(ev.data as string);\n };\n }\n\n private cancelPendingReconnect(): void {\n if (!this._reconnectPending) return;\n\n this._policy.cancel();\n this._reconnectPending = false;\n }\n\n private detachAndCloseSocket(socket: WebSocket): void {\n socket.onopen = null;\n socket.onclose = null;\n socket.onerror = null;\n socket.onmessage = null;\n socket.close();\n }\n\n private sendAllSubscriptions(): void {\n for (const [queryId, sub] of this._subscriptions) {\n this.sendSubscribeMessage(queryId, sub);\n }\n }\n\n private sendSubscribeMessage(\n queryId: string,\n subscription: ActiveSubscription,\n ): void {\n const message: HubMessage = {\n type: HubMessageType.Subscribe,\n queryId,\n payload: subscription.request,\n };\n if (this._supportsSubscriptionRevisions) {\n message.revision = subscription.revision;\n }\n this.sendMessage(message);\n }\n\n private sendMessage(message: HubMessage): void {\n if (this._socket?.readyState === WebSocket.OPEN) {\n this._socket.send(JSON.stringify(message));\n }\n }\n\n private handleMessage(rawData: string): void {\n try {\n const message = JSON.parse(rawData) as HubMessage;\n\n // Every received message is activity — skip keep-alive ping if data is flowing.\n this._keepAlive.recordActivity();\n\n switch (message.type) {\n case HubMessageType.Connected:\n this.handleConnected(message);\n break;\n case HubMessageType.QueryResult:\n this.handleQueryResult(message);\n break;\n case HubMessageType.Pong:\n this.handlePong(message);\n break;\n case HubMessageType.Unauthorized:\n console.warn('Hub: query unauthorized', message.queryId);\n this.handleUnauthorized(message);\n break;\n case HubMessageType.Error:\n if (this.isMessageForCurrentSubscription(message)) {\n console.error(\n 'Hub: query error',\n message.queryId,\n message.payload,\n );\n }\n break;\n }\n } catch (error) {\n console.error('Hub: error parsing message', error);\n }\n }\n\n private handleConnected(message: HubMessage): void {\n if (\n message.supportsSubscriptionRevisions !== true ||\n this._supportsSubscriptionRevisions\n ) {\n return;\n }\n\n this._supportsSubscriptionRevisions = true;\n\n // The legacy subscriptions sent on socket open keep this client compatible with older servers.\n // Ordered WebSocket delivery means these revision-aware replacements are processed afterwards.\n this.sendAllSubscriptions();\n }\n\n private handleQueryResult(message: HubMessage): void {\n if (!message.queryId) return;\n\n const sub = this._subscriptions.get(message.queryId);\n if (!sub || !this.isMessageForCurrentSubscription(message)) return;\n\n const result = message.payload as QueryResult<any>;\n sub.callback(result);\n }\n\n private handleUnauthorized(message: HubMessage): void {\n if (!message.queryId) return;\n\n const sub = this._subscriptions.get(message.queryId);\n if (!sub || !this.isMessageForCurrentSubscription(message)) return;\n\n this._subscriptions.delete(message.queryId);\n sub.callback(QueryResult.unauthorized());\n }\n\n private isMessageForCurrentSubscription(message: HubMessage): boolean {\n if (!message.queryId) return false;\n\n if (!this._supportsSubscriptionRevisions) {\n return (\n message.revision === undefined &&\n this._subscriptions.has(message.queryId)\n );\n }\n\n return (\n this.isValidRevision(message.revision) &&\n this._subscriptions.get(message.queryId)?.revision === message.revision\n );\n }\n\n private isValidRevision(revision: number | undefined): revision is number {\n return revision !== undefined && Number.isSafeInteger(revision) && revision > 0;\n }\n\n private getNextRevision(): number {\n if (this._nextRevision >= Number.MAX_SAFE_INTEGER) {\n throw new RangeError(\n 'WebSocket hub subscription revision exhausted the safe integer range',\n );\n }\n\n return ++this._nextRevision;\n }\n\n private handlePong(message: HubMessage): void {\n if (message.timestamp && this._lastPingSentTime) {\n const latency = Date.now() - message.timestamp;\n this._lastPongLatency = latency;\n this._latencySamples.push(latency);\n\n if (this._latencySamples.length > 100) {\n this._latencySamples.shift();\n }\n }\n }\n}\n"],"names":["HubMessageType","WebSocketHubConnection","_socket","_disconnected","_subscriptions","Map","_keepAlive","_lastPingSentTime","_lastPongLatency","_latencySamples","_nextRevision","_supportsSubscriptionRevisions","_reconnectPending","_url","pingIntervalMs","_policy","ReconnectPolicy","_microservice","HubConnectionKeepAlive","readyState","WebSocket","OPEN","Date","now","sendMessage","type","timestamp","queryCount","size","isConnected","lastPingLatency","averageLatency","length","reduce","a","b","subscribe","queryId","request","callback","subscription","revision","getNextRevision","set","ensureConnected","sendSubscribeMessage","unsubscribe","get","delete","message","close","dispose","clear","CONNECTING","cancelPendingReconnect","openSocket","stop","cancel","socket","undefined","detachAndCloseSocket","currentSocket","url","param","Globals","microserviceWSQueryArgument","encodeURIComponent","includes","onopen","console","log","reset","start","sendAllSubscriptions","onclose","scheduled","schedule","onerror","error","onmessage","ev","handleMessage","data","sub","payload","send","JSON","stringify","rawData","parse","recordActivity","handleConnected","handleQueryResult","handlePong","warn","handleUnauthorized","isMessageForCurrentSubscription","supportsSubscriptionRevisions","result","QueryResult","unauthorized","has","isValidRevision","Number","isSafeInteger","MAX_SAFE_INTEGER","RangeError","latency","push","shift"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"WebSocketMessage.js","sources":["../../../queries/WebSocketMessage.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\n/**\n * Represents the type of WebSocket message.\n */\nexport enum WebSocketMessageType {\n /**\n * A data message containing query results.\n */\n Data = 'Data',\n\n /**\n * A ping message sent from client to server.\n */\n Ping = 'Ping',\n\n /**\n * A pong message sent from server to client in response to a ping.\n */\n Pong = 'Pong'\n}\n\n/**\n * Represents a WebSocket message envelope.\n */\nexport type WebSocketMessage = {\n /**\n * The type of message.\n */\n type: WebSocketMessageType;\n\n /**\n * The timestamp when the message was sent (for ping/pong latency tracking).\n */\n timestamp?: number;\n\n /**\n * The payload data (for data messages).\n */\n /* eslint-disable @typescript-eslint/no-explicit-any */\n data?: any;\n /* eslint-enable @typescript-eslint/no-explicit-any */\n};\n"],"names":["WebSocketMessageType"],"mappings":"AAAA;AACA;AAEA;;IAGO,IAAKA,oBAAAA,iBAAAA,SAAAA,oBAAAA,EAAAA;AACR;;AAEC,QAAA,oBAAA,CAAA,MAAA,CAAA,GAAA,MAAA;AAGD;;AAEC,QAAA,oBAAA,CAAA,MAAA,CAAA,GAAA,MAAA;AAGD;;AAEC,QAAA,oBAAA,CAAA,MAAA,CAAA,GAAA,MAAA;AAbOA,IAAAA,OAAAA,oBAAAA;AAeX,CAAA,CAAA,EAAA;;;;"}
1
+ {"version":3,"file":"WebSocketMessage.js","sources":["../../../queries/WebSocketMessage.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\n/**\n * Represents the type of WebSocket message.\n */\nexport enum WebSocketMessageType {\n /**\n * A data message containing query results.\n */\n Data = 'Data',\n\n /**\n * A ping message sent from client to server.\n */\n Ping = 'Ping',\n\n /**\n * A pong message sent from server to client in response to a ping.\n */\n Pong = 'Pong'\n}\n\n/**\n * Represents a WebSocket message envelope.\n */\nexport type WebSocketMessage = {\n /**\n * The type of message.\n */\n type: WebSocketMessageType;\n\n /**\n * The timestamp when the message was sent (for ping/pong latency tracking).\n */\n timestamp?: number;\n\n /**\n * The payload data (for data messages).\n */\n /* eslint-disable @typescript-eslint/no-explicit-any */\n data?: any;\n /* eslint-enable @typescript-eslint/no-explicit-any */\n};\n"],"names":["WebSocketMessageType"],"mappings":"AAAA;AACA;AAEA;;IAGO,IAAKA,oBAAAA,iBAAAA,SAAAA,oBAAAA,EAAAA;AACR;;AAEC,QAAA,oBAAA,CAAA,MAAA,CAAA,GAAA,MAAA;AAGD;;AAEC,QAAA,oBAAA,CAAA,MAAA,CAAA,GAAA,MAAA;AAGD;;AAEC,QAAA,oBAAA,CAAA,MAAA,CAAA,GAAA,MAAA;AAbOA,IAAAA,OAAAA,oBAAAA;AAeX,CAAA,CAAA,EAAA;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"deserializeQueryModel.js","sources":["../../../queries/deserializeQueryModel.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 { Constructor, JsonSerializer } from '@cratis/fundamentals';\n\n/*\n * ⚠️ deserializeQueryModel / deserializeQueryModels are for use WITHIN this package only.\n *\n * JsonSerializer's converter registry is module state, and a consumer package can easily resolve a\n * different physical copy of @cratis/fundamentals than this one. Calling these from another package\n * therefore looks up Guid/Date/concept converters in the wrong registry and silently degrades those\n * values to plain deserialization. Other packages should use isPrimitiveModelType - which compares\n * against the JavaScript globals and is safe across copies - and deserialize through their own\n * JsonSerializer.\n */\n\n/**\n * Determines whether a model type is a JavaScript primitive wrapper rather than a real model.\n *\n * A query whose backend returns a primitive collection - `IEnumerable<string>`, `IEnumerable<int>` -\n * generates a proxy with `String`, `Number` or `Boolean` as its model type.\n * @param {Constructor} modelType The model type the query describes itself with.\n * @returns {boolean} True when the type is a primitive wrapper.\n */\nexport function isPrimitiveModelType(modelType: Constructor | null | undefined): boolean {\n return modelType === String || modelType === Number || modelType === Boolean;\n}\n\n/**\n * Deserializes a single query payload into its model type, passing primitives through untouched.\n *\n * {@link JsonSerializer.deserializeFromInstance} is destructive for primitive wrapper types: it\n * constructs `new String()` and copies declared fields onto it, which for a primitive means the\n * value is discarded and an empty wrapper object is produced. Primitives therefore need to bypass\n * deserialization entirely - they already arrive in their final shape.\n * @param {Constructor} modelType The model type to deserialize into.\n * @param {unknown} data The payload to deserialize.\n * @returns {TDataType} The deserialized instance, or the payload unchanged for primitive types.\n */\nexport function deserializeQueryModel<TDataType>(modelType: Constructor | null | undefined, data: unknown): TDataType {\n if (!modelType || modelType === Object || isPrimitiveModelType(modelType)) {\n return data as TDataType;\n }\n\n return JsonSerializer.deserializeFromInstance(modelType, data) as TDataType;\n}\n\n/**\n * Deserializes a query payload collection into its model type, passing primitives through untouched.\n *\n * See {@link deserializeQueryModel} for why primitive model types must bypass deserialization.\n * @param {Constructor} modelType The instance type of the items to deserialize into.\n * @param {unknown} data The payload to deserialize. A non-array payload yields an empty collection.\n * @returns {TDataType[]} The deserialized items, or the items unchanged for primitive types.\n */\nexport function deserializeQueryModels<TDataType>(modelType: Constructor | null | undefined, data: unknown): TDataType[] {\n if (!Array.isArray(data)) {\n return [];\n }\n\n if (!modelType || modelType === Object || isPrimitiveModelType(modelType)) {\n return Array.from(data) as TDataType[];\n }\n\n return JsonSerializer.deserializeArrayFromInstance(modelType, data) as TDataType[];\n}\n"],"names":["isPrimitiveModelType","modelType","String","Number","Boolean","deserializeQueryModel","data","Object","JsonSerializer","deserializeFromInstance","deserializeQueryModels","Array","isArray","from","deserializeArrayFromInstance"],"mappings":";;AAAA;AACA;AAIA;;;;;;;;;;;;;;;;IAmBO,SAASA,oBAAAA,CAAqBC,SAAyC,EAAA;AAC1E,IAAA,OAAOA,SAAAA,KAAcC,MAAAA,IAAUD,SAAAA,KAAcE,MAAAA,IAAUF,SAAAA,KAAcG,OAAAA;AACzE;AAEA;;;;;;;;;;AAUC,IACM,SAASC,qBAAAA,CAAiCJ,SAAyC,EAAEK,IAAa,EAAA;AACrG,IAAA,IAAI,CAACL,SAAAA,IAAaA,SAAAA,KAAcM,MAAAA,IAAUP,qBAAqBC,SAAAA,CAAAA,EAAY;QACvE,OAAOK,IAAAA;AACX,IAAA;IAEA,OAAOE,cAAAA,CAAeC,uBAAuB,CAACR,SAAAA,EAAWK,IAAAA,CAAAA;AAC7D;AAEA;;;;;;;AAOC,IACM,SAASI,sBAAAA,CAAkCT,SAAyC,EAAEK,IAAa,EAAA;AACtG,IAAA,IAAI,CAACK,KAAAA,CAAMC,OAAO,CAACN,IAAAA,CAAAA,EAAO;AACtB,QAAA,OAAO,EAAE;AACb,IAAA;AAEA,IAAA,IAAI,CAACL,SAAAA,IAAaA,SAAAA,KAAcM,MAAAA,IAAUP,qBAAqBC,SAAAA,CAAAA,EAAY;QACvE,OAAOU,KAAAA,CAAME,IAAI,CAACP,IAAAA,CAAAA;AACtB,IAAA;IAEA,OAAOE,cAAAA,CAAeM,4BAA4B,CAACb,SAAAA,EAAWK,IAAAA,CAAAA;AAClE;;;;"}
1
+ {"version":3,"file":"deserializeQueryModel.js","sources":["../../../queries/deserializeQueryModel.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 { Constructor, JsonSerializer } from '@cratis/fundamentals';\n\n/*\n * ⚠️ deserializeQueryModel / deserializeQueryModels are for use WITHIN this package only.\n *\n * JsonSerializer's converter registry is module state, and a consumer package can easily resolve a\n * different physical copy of @cratis/fundamentals than this one. Calling these from another package\n * therefore looks up Guid/Date/concept converters in the wrong registry and silently degrades those\n * values to plain deserialization. Other packages should use isPrimitiveModelType - which compares\n * against the JavaScript globals and is safe across copies - and deserialize through their own\n * JsonSerializer.\n */\n\n/**\n * Determines whether a model type is a JavaScript primitive wrapper rather than a real model.\n *\n * A query whose backend returns a primitive collection - `IEnumerable<string>`, `IEnumerable<int>` -\n * generates a proxy with `String`, `Number` or `Boolean` as its model type.\n * @param {Constructor} modelType The model type the query describes itself with.\n * @returns {boolean} True when the type is a primitive wrapper.\n */\nexport function isPrimitiveModelType(modelType: Constructor | null | undefined): boolean {\n return modelType === String || modelType === Number || modelType === Boolean;\n}\n\n/**\n * Deserializes a single query payload into its model type, passing primitives through untouched.\n *\n * {@link JsonSerializer.deserializeFromInstance} is destructive for primitive wrapper types: it\n * constructs `new String()` and copies declared fields onto it, which for a primitive means the\n * value is discarded and an empty wrapper object is produced. Primitives therefore need to bypass\n * deserialization entirely - they already arrive in their final shape.\n * @param {Constructor} modelType The model type to deserialize into.\n * @param {unknown} data The payload to deserialize.\n * @returns {TDataType} The deserialized instance, or the payload unchanged for primitive types.\n */\nexport function deserializeQueryModel<TDataType>(modelType: Constructor | null | undefined, data: unknown): TDataType {\n if (!modelType || modelType === Object || isPrimitiveModelType(modelType)) {\n return data as TDataType;\n }\n\n return JsonSerializer.deserializeFromInstance(modelType, data) as TDataType;\n}\n\n/**\n * Deserializes a query payload collection into its model type, passing primitives through untouched.\n *\n * See {@link deserializeQueryModel} for why primitive model types must bypass deserialization.\n * @param {Constructor} modelType The instance type of the items to deserialize into.\n * @param {unknown} data The payload to deserialize. A non-array payload yields an empty collection.\n * @returns {TDataType[]} The deserialized items, or the items unchanged for primitive types.\n */\nexport function deserializeQueryModels<TDataType>(modelType: Constructor | null | undefined, data: unknown): TDataType[] {\n if (!Array.isArray(data)) {\n return [];\n }\n\n if (!modelType || modelType === Object || isPrimitiveModelType(modelType)) {\n return Array.from(data) as TDataType[];\n }\n\n return JsonSerializer.deserializeArrayFromInstance(modelType, data) as TDataType[];\n}\n"],"names":["isPrimitiveModelType","modelType","String","Number","Boolean","deserializeQueryModel","data","Object","JsonSerializer","deserializeFromInstance","deserializeQueryModels","Array","isArray","from","deserializeArrayFromInstance"],"mappings":";;AAAA;AACA;AAIA;;;;;;;;;;;;;;;;IAmBO,SAASA,oBAAAA,CAAqBC,SAAyC,EAAA;AAC1E,IAAA,OAAOA,SAAAA,KAAcC,MAAAA,IAAUD,SAAAA,KAAcE,MAAAA,IAAUF,SAAAA,KAAcG,OAAAA;AACzE;AAEA;;;;;;;;;;AAUC,IACM,SAASC,qBAAAA,CAAiCJ,SAAyC,EAAEK,IAAa,EAAA;AACrG,IAAA,IAAI,CAACL,SAAAA,IAAaA,SAAAA,KAAcM,MAAAA,IAAUP,qBAAqBC,SAAAA,CAAAA,EAAY;QACvE,OAAOK,IAAAA;AACX,IAAA;IAEA,OAAOE,cAAAA,CAAeC,uBAAuB,CAACR,SAAAA,EAAWK,IAAAA,CAAAA;AAC7D;AAEA;;;;;;;AAOC,IACM,SAASI,sBAAAA,CAAkCT,SAAyC,EAAEK,IAAa,EAAA;AACtG,IAAA,IAAI,CAACK,KAAAA,CAAMC,OAAO,CAACN,IAAAA,CAAAA,EAAO;AACtB,QAAA,OAAO,EAAE;AACb,IAAA;AAEA,IAAA,IAAI,CAACL,SAAAA,IAAaA,SAAAA,KAAcM,MAAAA,IAAUP,qBAAqBC,SAAAA,CAAAA,EAAY;QACvE,OAAOU,KAAAA,CAAME,IAAI,CAACP,IAAAA,CAAAA;AACtB,IAAA;IAEA,OAAOE,cAAAA,CAAeM,4BAA4B,CAACb,SAAAA,EAAWK,IAAAA,CAAAA;AAClE;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"isAbortError.js","sources":["../../../queries/isAbortError.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\n/**\n * Determines whether an error is the rejection produced by aborting a request through an\n * {@link AbortSignal} - as opposed to a genuine transport failure.\n *\n * Deliberately kept out of the `queries` barrel: it is an internal detail shared by the query\n * transport and {@link QueryFor}, not public surface for consumers to depend on.\n * @param error The error to inspect.\n * @returns True if the error represents an aborted request, false otherwise.\n */\nexport function isAbortError(error: unknown): boolean {\n return (error as { name?: string })?.name === 'AbortError';\n}\n"],"names":["isAbortError","error","name"],"mappings":"AAAA;AACA;AAEA;;;;;;;;IASO,SAASA,YAAAA,CAAaC,KAAc,EAAA;IACvC,OAAQA,OAA6BC,IAAAA,KAAS,YAAA;AAClD;;;;"}
1
+ {"version":3,"file":"isAbortError.js","sources":["../../../queries/isAbortError.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\n/**\n * Determines whether an error is the rejection produced by aborting a request through an\n * {@link AbortSignal} - as opposed to a genuine transport failure.\n *\n * Deliberately kept out of the `queries` barrel: it is an internal detail shared by the query\n * transport and {@link QueryFor}, not public surface for consumers to depend on.\n * @param error The error to inspect.\n * @returns True if the error represents an aborted request, false otherwise.\n */\nexport function isAbortError(error: unknown): boolean {\n return (error as { name?: string })?.name === 'AbortError';\n}\n"],"names":["isAbortError","error","name"],"mappings":"AAAA;AACA;AAEA;;;;;;;;IASO,SAASA,YAAAA,CAAaC,KAAc,EAAA;IACvC,OAAQA,OAA6BC,IAAAA,KAAS,YAAA;AAClD;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"reconcileQueryData.js","sources":["../../../queries/reconcileQueryData.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 { deepEqual } from '../deepEqual';\n\n/**\n * Resolves the conventional identity of an item so it can be matched against its previous version.\n *\n * Uses the `id` property, the same strategy the server-side change-set computation applies, and\n * reduces concept-style identities (objects with a meaningful `toString()`) to a comparable value.\n * @param {unknown} item The item to resolve identity for.\n * @returns {unknown} The identity value, or `undefined` when the item carries no usable identity.\n */\nfunction getIdentity(item: unknown): unknown {\n const id = (item as Record<string, unknown>)?.id;\n\n if (id === null || id === undefined) {\n return undefined;\n }\n\n if (typeof id === 'object') {\n const stringValue = id.toString();\n return stringValue !== '[object Object]' ? stringValue : JSON.stringify(id);\n }\n\n return id;\n}\n\n/**\n * Reconciles a full payload against the previous one, carrying over the previous object references\n * for every item that did not actually change.\n *\n * Observable queries re-deliver a complete snapshot whenever a subscription is (re-)established.\n * Deserializing that snapshot produces entirely new object references, so consumers that compare by\n * reference — memoized components, effect dependencies — treat every item as changed even when the\n * payload is identical to what they already display. Reconciling restores referential stability:\n * unchanged items keep their previous reference, and when nothing changed at all the previous\n * payload itself is returned so callers can detect \"no change\" with a single `===`.\n *\n * Items are matched by their `id` when present, falling back to position for identity-less items.\n * @template T The payload type.\n * @param {T} previous The payload currently held.\n * @param {T} next The freshly received payload.\n * @returns {T} `previous` when nothing changed; otherwise the new payload with unchanged items carried over by reference.\n */\nexport function reconcileQueryData<T>(previous: T, next: T): T {\n if (previous === next) {\n return previous;\n }\n\n if (Array.isArray(previous) && Array.isArray(next)) {\n return reconcileArray(previous, next) as T;\n }\n\n return deepEqual(previous, next) ? previous : next;\n}\n\n/**\n * Reconciles two arrays element by element, preserving previous references for unchanged items.\n * @param {unknown[]} previous The array currently held.\n * @param {unknown[]} next The freshly received array.\n * @returns {unknown[]} `previous` when the arrays are equivalent; otherwise a new array reusing unchanged items.\n */\nfunction reconcileArray(previous: unknown[], next: unknown[]): unknown[] {\n const previousByIdentity = new Map<unknown, unknown>();\n\n for (const item of previous) {\n const identity = getIdentity(item);\n\n // Keep the first occurrence — duplicate identities are not a shape we can reconcile\n // meaningfully, and preferring the first keeps the result deterministic.\n if (identity !== undefined && !previousByIdentity.has(identity)) {\n previousByIdentity.set(identity, item);\n }\n }\n\n let changed = previous.length !== next.length;\n\n const reconciled = next.map((item, index) => {\n const identity = getIdentity(item);\n const candidate = identity !== undefined ? previousByIdentity.get(identity) : previous[index];\n\n if (candidate !== undefined && deepEqual(candidate, item)) {\n // An unchanged item that moved still leaves the collection changed as a whole, but the\n // item itself keeps its reference so only the ordering re-renders, not its content.\n if (candidate !== previous[index]) {\n changed = true;\n }\n\n return candidate;\n }\n\n changed = true;\n return item;\n });\n\n return changed ? reconciled : previous;\n}\n"],"names":["getIdentity","item","id","undefined","stringValue","toString","JSON","stringify","reconcileQueryData","previous","next","Array","isArray","reconcileArray","deepEqual","previousByIdentity","Map","identity","has","set","changed","length","reconciled","map","index","candidate","get"],"mappings":";;AAAA;AACA;AAIA;;;;;;;IAQA,SAASA,YAAYC,IAAa,EAAA;AAC9B,IAAA,MAAMC,KAAMD,IAAAA,EAAkCC,EAAAA;IAE9C,IAAIA,EAAAA,KAAO,IAAA,IAAQA,EAAAA,KAAOC,SAAAA,EAAW;QACjC,OAAOA,SAAAA;AACX,IAAA;IAEA,IAAI,OAAOD,OAAO,QAAA,EAAU;QACxB,MAAME,WAAAA,GAAcF,GAAGG,QAAQ,EAAA;AAC/B,QAAA,OAAOD,WAAAA,KAAgB,iBAAA,GAAoBA,WAAAA,GAAcE,IAAAA,CAAKC,SAAS,CAACL,EAAAA,CAAAA;AAC5E,IAAA;IAEA,OAAOA,EAAAA;AACX;AAEA;;;;;;;;;;;;;;;;AAgBC,IACM,SAASM,kBAAAA,CAAsBC,QAAW,EAAEC,IAAO,EAAA;AACtD,IAAA,IAAID,aAAaC,IAAAA,EAAM;QACnB,OAAOD,QAAAA;AACX,IAAA;AAEA,IAAA,IAAIE,MAAMC,OAAO,CAACH,aAAaE,KAAAA,CAAMC,OAAO,CAACF,IAAAA,CAAAA,EAAO;AAChD,QAAA,OAAOG,eAAeJ,QAAAA,EAAUC,IAAAA,CAAAA;AACpC,IAAA;IAEA,OAAOI,SAAAA,CAAUL,QAAAA,EAAUC,IAAAA,CAAAA,GAAQD,QAAAA,GAAWC,IAAAA;AAClD;AAEA;;;;;AAKC,IACD,SAASG,cAAAA,CAAeJ,QAAmB,EAAEC,IAAe,EAAA;AACxD,IAAA,MAAMK,qBAAqB,IAAIC,GAAAA,EAAAA;IAE/B,KAAK,MAAMf,QAAQQ,QAAAA,CAAU;AACzB,QAAA,MAAMQ,WAAWjB,WAAAA,CAAYC,IAAAA,CAAAA;;;AAI7B,QAAA,IAAIgB,aAAad,SAAAA,IAAa,CAACY,kBAAAA,CAAmBG,GAAG,CAACD,QAAAA,CAAAA,EAAW;YAC7DF,kBAAAA,CAAmBI,GAAG,CAACF,QAAAA,EAAUhB,IAAAA,CAAAA;AACrC,QAAA;AACJ,IAAA;AAEA,IAAA,IAAImB,OAAAA,GAAUX,QAAAA,CAASY,MAAM,KAAKX,KAAKW,MAAM;AAE7C,IAAA,MAAMC,UAAAA,GAAaZ,IAAAA,CAAKa,GAAG,CAAC,CAACtB,IAAAA,EAAMuB,KAAAA,GAAAA;AAC/B,QAAA,MAAMP,WAAWjB,WAAAA,CAAYC,IAAAA,CAAAA;QAC7B,MAAMwB,SAAAA,GAAYR,aAAad,SAAAA,GAAYY,kBAAAA,CAAmBW,GAAG,CAACT,QAAAA,CAAAA,GAAYR,QAAQ,CAACe,KAAAA,CAAM;AAE7F,QAAA,IAAIC,SAAAA,KAActB,SAAAA,IAAaW,SAAAA,CAAUW,SAAAA,EAAWxB,IAAAA,CAAAA,EAAO;;;AAGvD,YAAA,IAAIwB,SAAAA,KAAchB,QAAQ,CAACe,KAAAA,CAAM,EAAE;gBAC/BJ,OAAAA,GAAU,IAAA;AACd,YAAA;YAEA,OAAOK,SAAAA;AACX,QAAA;QAEAL,OAAAA,GAAU,IAAA;QACV,OAAOnB,IAAAA;AACX,IAAA,CAAA,CAAA;AAEA,IAAA,OAAOmB,UAAUE,UAAAA,GAAab,QAAAA;AAClC;;;;"}
1
+ {"version":3,"file":"reconcileQueryData.js","sources":["../../../queries/reconcileQueryData.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 { deepEqual } from '../deepEqual';\n\n/**\n * Resolves the conventional identity of an item so it can be matched against its previous version.\n *\n * Uses the `id` property, the same strategy the server-side change-set computation applies, and\n * reduces concept-style identities (objects with a meaningful `toString()`) to a comparable value.\n * @param {unknown} item The item to resolve identity for.\n * @returns {unknown} The identity value, or `undefined` when the item carries no usable identity.\n */\nfunction getIdentity(item: unknown): unknown {\n const id = (item as Record<string, unknown>)?.id;\n\n if (id === null || id === undefined) {\n return undefined;\n }\n\n if (typeof id === 'object') {\n const stringValue = id.toString();\n return stringValue !== '[object Object]' ? stringValue : JSON.stringify(id);\n }\n\n return id;\n}\n\n/**\n * Reconciles a full payload against the previous one, carrying over the previous object references\n * for every item that did not actually change.\n *\n * Observable queries re-deliver a complete snapshot whenever a subscription is (re-)established.\n * Deserializing that snapshot produces entirely new object references, so consumers that compare by\n * reference — memoized components, effect dependencies — treat every item as changed even when the\n * payload is identical to what they already display. Reconciling restores referential stability:\n * unchanged items keep their previous reference, and when nothing changed at all the previous\n * payload itself is returned so callers can detect \"no change\" with a single `===`.\n *\n * Items are matched by their `id` when present, falling back to position for identity-less items.\n * @template T The payload type.\n * @param {T} previous The payload currently held.\n * @param {T} next The freshly received payload.\n * @returns {T} `previous` when nothing changed; otherwise the new payload with unchanged items carried over by reference.\n */\nexport function reconcileQueryData<T>(previous: T, next: T): T {\n if (previous === next) {\n return previous;\n }\n\n if (Array.isArray(previous) && Array.isArray(next)) {\n return reconcileArray(previous, next) as T;\n }\n\n return deepEqual(previous, next) ? previous : next;\n}\n\n/**\n * Reconciles two arrays element by element, preserving previous references for unchanged items.\n * @param {unknown[]} previous The array currently held.\n * @param {unknown[]} next The freshly received array.\n * @returns {unknown[]} `previous` when the arrays are equivalent; otherwise a new array reusing unchanged items.\n */\nfunction reconcileArray(previous: unknown[], next: unknown[]): unknown[] {\n const previousByIdentity = new Map<unknown, unknown>();\n\n for (const item of previous) {\n const identity = getIdentity(item);\n\n // Keep the first occurrence — duplicate identities are not a shape we can reconcile\n // meaningfully, and preferring the first keeps the result deterministic.\n if (identity !== undefined && !previousByIdentity.has(identity)) {\n previousByIdentity.set(identity, item);\n }\n }\n\n let changed = previous.length !== next.length;\n\n const reconciled = next.map((item, index) => {\n const identity = getIdentity(item);\n const candidate = identity !== undefined ? previousByIdentity.get(identity) : previous[index];\n\n if (candidate !== undefined && deepEqual(candidate, item)) {\n // An unchanged item that moved still leaves the collection changed as a whole, but the\n // item itself keeps its reference so only the ordering re-renders, not its content.\n if (candidate !== previous[index]) {\n changed = true;\n }\n\n return candidate;\n }\n\n changed = true;\n return item;\n });\n\n return changed ? reconciled : previous;\n}\n"],"names":["getIdentity","item","id","undefined","stringValue","toString","JSON","stringify","reconcileQueryData","previous","next","Array","isArray","reconcileArray","deepEqual","previousByIdentity","Map","identity","has","set","changed","length","reconciled","map","index","candidate","get"],"mappings":";;AAAA;AACA;AAIA;;;;;;;IAQA,SAASA,YAAYC,IAAa,EAAA;AAC9B,IAAA,MAAMC,KAAMD,IAAAA,EAAkCC,EAAAA;IAE9C,IAAIA,EAAAA,KAAO,IAAA,IAAQA,EAAAA,KAAOC,SAAAA,EAAW;QACjC,OAAOA,SAAAA;AACX,IAAA;IAEA,IAAI,OAAOD,OAAO,QAAA,EAAU;QACxB,MAAME,WAAAA,GAAcF,GAAGG,QAAQ,EAAA;AAC/B,QAAA,OAAOD,WAAAA,KAAgB,iBAAA,GAAoBA,WAAAA,GAAcE,IAAAA,CAAKC,SAAS,CAACL,EAAAA,CAAAA;AAC5E,IAAA;IAEA,OAAOA,EAAAA;AACX;AAEA;;;;;;;;;;;;;;;;AAgBC,IACM,SAASM,kBAAAA,CAAsBC,QAAW,EAAEC,IAAO,EAAA;AACtD,IAAA,IAAID,aAAaC,IAAAA,EAAM;QACnB,OAAOD,QAAAA;AACX,IAAA;AAEA,IAAA,IAAIE,MAAMC,OAAO,CAACH,aAAaE,KAAAA,CAAMC,OAAO,CAACF,IAAAA,CAAAA,EAAO;AAChD,QAAA,OAAOG,eAAeJ,QAAAA,EAAUC,IAAAA,CAAAA;AACpC,IAAA;IAEA,OAAOI,SAAAA,CAAUL,QAAAA,EAAUC,IAAAA,CAAAA,GAAQD,QAAAA,GAAWC,IAAAA;AAClD;AAEA;;;;;AAKC,IACD,SAASG,cAAAA,CAAeJ,QAAmB,EAAEC,IAAe,EAAA;AACxD,IAAA,MAAMK,qBAAqB,IAAIC,GAAAA,EAAAA;IAE/B,KAAK,MAAMf,QAAQQ,QAAAA,CAAU;AACzB,QAAA,MAAMQ,WAAWjB,WAAAA,CAAYC,IAAAA,CAAAA;;;AAI7B,QAAA,IAAIgB,aAAad,SAAAA,IAAa,CAACY,kBAAAA,CAAmBG,GAAG,CAACD,QAAAA,CAAAA,EAAW;YAC7DF,kBAAAA,CAAmBI,GAAG,CAACF,QAAAA,EAAUhB,IAAAA,CAAAA;AACrC,QAAA;AACJ,IAAA;AAEA,IAAA,IAAImB,OAAAA,GAAUX,QAAAA,CAASY,MAAM,KAAKX,KAAKW,MAAM;AAE7C,IAAA,MAAMC,UAAAA,GAAaZ,IAAAA,CAAKa,GAAG,CAAC,CAACtB,IAAAA,EAAMuB,KAAAA,GAAAA;AAC/B,QAAA,MAAMP,WAAWjB,WAAAA,CAAYC,IAAAA,CAAAA;QAC7B,MAAMwB,SAAAA,GAAYR,aAAad,SAAAA,GAAYY,kBAAAA,CAAmBW,GAAG,CAACT,QAAAA,CAAAA,GAAYR,QAAQ,CAACe,KAAAA,CAAM;AAE7F,QAAA,IAAIC,SAAAA,KAActB,SAAAA,IAAaW,SAAAA,CAAUW,SAAAA,EAAWxB,IAAAA,CAAAA,EAAO;;;AAGvD,YAAA,IAAIwB,SAAAA,KAAchB,QAAQ,CAACe,KAAAA,CAAM,EAAE;gBAC/BJ,OAAAA,GAAU,IAAA;AACd,YAAA;YAEA,OAAOK,SAAAA;AACX,QAAA;QAEAL,OAAAA,GAAU,IAAA;QACV,OAAOnB,IAAAA;AACX,IAAA,CAAA,CAAA;AAEA,IAAA,OAAOmB,UAAUE,UAAAA,GAAab,QAAAA;AAClC;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"ParameterDescriptor.js","sources":["../../../reflection/ParameterDescriptor.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 { Constructor } from '@cratis/fundamentals';\n\n/**\n * Represents a parameter descriptor.\n */\nexport class ParameterDescriptor {\n /**\n * Initializes a new instance of the {@link ParameterDescriptor} class.\n * @param name Name of the parameter.\n * @param type Type of the parameter.\n * @param isEnumerable Whether the parameter is an enumerable (collection) type.\n */\n constructor(readonly name: string, readonly type: Constructor, readonly isEnumerable: boolean = false) {\n }\n}\n"],"names":["ParameterDescriptor","type","isEnumerable","name"],"mappings":"AAAA;AACA;AAIA;;AAEC,IACM,MAAMA,mBAAAA,CAAAA;;;;AACT;;;;;QAMA,WAAA,CAAY,IAAqB,EAAWC,IAAiB,EAAWC,YAAAA,GAAwB,KAAK,CAAE;aAAlFC,IAAAA,GAAAA,IAAAA;aAAuBF,IAAAA,GAAAA,IAAAA;aAA4BC,YAAAA,GAAAA,YAAAA;AACxE,IAAA;AACJ;;;;"}
1
+ {"version":3,"file":"ParameterDescriptor.js","sources":["../../../reflection/ParameterDescriptor.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 { Constructor } from '@cratis/fundamentals';\n\n/**\n * Represents a parameter descriptor.\n */\nexport class ParameterDescriptor {\n /**\n * Initializes a new instance of the {@link ParameterDescriptor} class.\n * @param name Name of the parameter.\n * @param type Type of the parameter.\n * @param isEnumerable Whether the parameter is an enumerable (collection) type.\n */\n constructor(readonly name: string, readonly type: Constructor, readonly isEnumerable: boolean = false) {\n }\n}\n"],"names":["ParameterDescriptor","type","isEnumerable","name"],"mappings":"AAAA;AACA;AAIA;;AAEC,IACM,MAAMA,mBAAAA,CAAAA;;;;AACT;;;;;QAMA,WAAA,CAAY,IAAqB,EAAWC,IAAiB,EAAWC,YAAAA,GAAwB,KAAK,CAAE;aAAlFC,IAAAA,GAAAA,IAAAA;aAAuBF,IAAAA,GAAAA,IAAAA;aAA4BC,YAAAA,GAAAA,YAAAA;AACxE,IAAA;AACJ;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"ParametersHelper.js","sources":["../../../reflection/ParametersHelper.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 { IHaveParameters } from './IHaveParameters';\n\n/**\n * Helper for working with types that have parameters.\n */\nexport const ParametersHelper = {\n /**\n * Collects the parameter values from an instance based on its parameter descriptors.\n * @param instance The instance to collect parameter values from.\n * @returns A record of parameter names to their values.\n */\n collectParameterValues(instance: IHaveParameters): Record<string, unknown> {\n const values: Record<string, unknown> = {};\n for (const descriptor of instance.parameterDescriptors) {\n const value = (instance as unknown as Record<string, unknown>)[descriptor.name];\n if (value !== undefined && value !== null) {\n values[descriptor.name] = value;\n }\n }\n return values;\n }\n};\n"],"names":["ParametersHelper","collectParameterValues","instance","values","descriptor","parameterDescriptors","value","name","undefined"],"mappings":"AAAA;AACA;AAIA;;UAGaA,gBAAAA,GAAmB;AAC5B;;;;AAIC,QACDC,wBAAuBC,QAAyB,EAAA;AAC5C,QAAA,MAAMC,SAAkC,EAAC;AACzC,QAAA,KAAK,MAAMC,UAAAA,IAAcF,QAAAA,CAASG,oBAAoB,CAAE;AACpD,YAAA,MAAMC,QAAQ,QAAgD,CAACF,UAAAA,CAAWG,IAAI,CAAC;YAC/E,IAAID,KAAAA,KAAUE,SAAAA,IAAaF,KAAAA,KAAU,IAAA,EAAM;AACvCH,gBAAAA,MAAM,CAACC,UAAAA,CAAWG,IAAI,CAAC,GAAGD,KAAAA;AAC9B,YAAA;AACJ,QAAA;QACA,OAAOH,MAAAA;AACX,IAAA;AACJ;;;;"}
1
+ {"version":3,"file":"ParametersHelper.js","sources":["../../../reflection/ParametersHelper.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 { IHaveParameters } from './IHaveParameters';\n\n/**\n * Helper for working with types that have parameters.\n */\nexport const ParametersHelper = {\n /**\n * Collects the parameter values from an instance based on its parameter descriptors.\n * @param instance The instance to collect parameter values from.\n * @returns A record of parameter names to their values.\n */\n collectParameterValues(instance: IHaveParameters): Record<string, unknown> {\n const values: Record<string, unknown> = {};\n for (const descriptor of instance.parameterDescriptors) {\n const value = (instance as unknown as Record<string, unknown>)[descriptor.name];\n if (value !== undefined && value !== null) {\n values[descriptor.name] = value;\n }\n }\n return values;\n }\n};\n"],"names":["ParametersHelper","collectParameterValues","instance","values","descriptor","parameterDescriptors","value","name","undefined"],"mappings":"AAAA;AACA;AAIA;;UAGaA,gBAAAA,GAAmB;AAC5B;;;;AAIC,QACDC,wBAAuBC,QAAyB,EAAA;AAC5C,QAAA,MAAMC,SAAkC,EAAC;AACzC,QAAA,KAAK,MAAMC,UAAAA,IAAcF,QAAAA,CAASG,oBAAoB,CAAE;AACpD,YAAA,MAAMC,QAAQ,QAAgD,CAACF,UAAAA,CAAWG,IAAI,CAAC;YAC/E,IAAID,KAAAA,KAAUE,SAAAA,IAAaF,KAAAA,KAAU,IAAA,EAAM;AACvCH,gBAAAA,MAAM,CAACC,UAAAA,CAAWG,IAAI,CAAC,GAAGD,KAAAA;AAC9B,YAAA;AACJ,QAAA;QACA,OAAOH,MAAAA;AACX,IAAA;AACJ;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"PropertyDescriptor.js","sources":["../../../reflection/PropertyDescriptor.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 { Constructor } from '@cratis/fundamentals';\n\n/**\n * Represents a property descriptor.\n */\nexport class PropertyDescriptor {\n /**\n * Initializes a new instance of the {@link PropertyDescriptor} class.\n * @param name Name of the property.\n * @param type Type of the property.\n * @param isOptional Whether the property is optional (nullable).\n */\n constructor(readonly name: string, readonly type: Constructor, readonly isOptional: boolean = false) {\n }\n}\n"],"names":["PropertyDescriptor","type","isOptional","name"],"mappings":"AAAA;AACA;AAIA;;AAEC,IACM,MAAMA,kBAAAA,CAAAA;;;;AACT;;;;;QAMA,WAAA,CAAY,IAAqB,EAAWC,IAAiB,EAAWC,UAAAA,GAAsB,KAAK,CAAE;aAAhFC,IAAAA,GAAAA,IAAAA;aAAuBF,IAAAA,GAAAA,IAAAA;aAA4BC,UAAAA,GAAAA,UAAAA;AACxE,IAAA;AACJ;;;;"}
1
+ {"version":3,"file":"PropertyDescriptor.js","sources":["../../../reflection/PropertyDescriptor.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 { Constructor } from '@cratis/fundamentals';\n\n/**\n * Represents a property descriptor.\n */\nexport class PropertyDescriptor {\n /**\n * Initializes a new instance of the {@link PropertyDescriptor} class.\n * @param name Name of the property.\n * @param type Type of the property.\n * @param isOptional Whether the property is optional (nullable).\n */\n constructor(readonly name: string, readonly type: Constructor, readonly isOptional: boolean = false) {\n }\n}\n"],"names":["PropertyDescriptor","type","isOptional","name"],"mappings":"AAAA;AACA;AAIA;;AAEC,IACM,MAAMA,kBAAAA,CAAAA;;;;AACT;;;;;QAMA,WAAA,CAAY,IAAqB,EAAWC,IAAiB,EAAWC,UAAAA,GAAsB,KAAK,CAAE;aAAhFC,IAAAA,GAAAA,IAAAA;aAAuBF,IAAAA,GAAAA,IAAAA;aAA4BC,UAAAA,GAAAA,UAAAA;AACxE,IAAA;AACJ;;"}