quidproquo-web-admin 0.1.18 → 0.1.20

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 (31) hide show
  1. package/lib/commonjs/LogViewer/logic/actionComponentMap/webserver/index.js +1 -2
  2. package/lib/commonjs/LogViewer/logic/actionComponentMap/webserver/index.js.map +1 -1
  3. package/lib/commonjs/LogViewer/logic/actionComponentMap/webserver/webserverDnsActionComponentMap.js +1 -0
  4. package/lib/commonjs/LogViewer/logic/actionComponentMap/webserver/webserverDnsActionComponentMap.js.map +1 -1
  5. package/lib/commonjs/adminApp/actions/askApplySessionEventToLog.js +1 -3
  6. package/lib/commonjs/adminApp/actions/askApplySessionEventToLog.js.map +1 -1
  7. package/lib/commonjs/adminApp/stateUpdaters/sessionLog/eventAppended.js +11 -5
  8. package/lib/commonjs/adminApp/stateUpdaters/sessionLog/eventAppended.js.map +1 -1
  9. package/lib/commonjs/adminApp/stateUpdaters/sessionLog/eventSaved.js +4 -5
  10. package/lib/commonjs/adminApp/stateUpdaters/sessionLog/eventSaved.js.map +1 -1
  11. package/lib/commonjs/adminApp/testHelpers/makeSessionEvent.js +1 -2
  12. package/lib/commonjs/adminApp/testHelpers/makeSessionEvent.js.map +1 -1
  13. package/lib/esm/LogViewer/logic/actionComponentMap/webserver/index.js +0 -2
  14. package/lib/esm/LogViewer/logic/actionComponentMap/webserver/index.js.map +1 -1
  15. package/lib/esm/LogViewer/logic/actionComponentMap/webserver/webserverDnsActionComponentMap.js +1 -0
  16. package/lib/esm/LogViewer/logic/actionComponentMap/webserver/webserverDnsActionComponentMap.js.map +1 -1
  17. package/lib/esm/adminApp/actions/askApplySessionEventToLog.js +2 -4
  18. package/lib/esm/adminApp/actions/askApplySessionEventToLog.js.map +1 -1
  19. package/lib/esm/adminApp/stateUpdaters/sessionLog/eventAppended.js +16 -5
  20. package/lib/esm/adminApp/stateUpdaters/sessionLog/eventAppended.js.map +1 -1
  21. package/lib/esm/adminApp/stateUpdaters/sessionLog/eventSaved.js +10 -5
  22. package/lib/esm/adminApp/stateUpdaters/sessionLog/eventSaved.js.map +1 -1
  23. package/lib/esm/adminApp/testHelpers/makeSessionEvent.js +1 -2
  24. package/lib/esm/adminApp/testHelpers/makeSessionEvent.js.map +1 -1
  25. package/package.json +7 -7
  26. package/lib/commonjs/LogViewer/logic/actionComponentMap/webserver/webserverOpenApiSpecActionComponentMap.d.ts +0 -2
  27. package/lib/commonjs/LogViewer/logic/actionComponentMap/webserver/webserverOpenApiSpecActionComponentMap.js +0 -8
  28. package/lib/commonjs/LogViewer/logic/actionComponentMap/webserver/webserverOpenApiSpecActionComponentMap.js.map +0 -1
  29. package/lib/esm/LogViewer/logic/actionComponentMap/webserver/webserverOpenApiSpecActionComponentMap.d.ts +0 -2
  30. package/lib/esm/LogViewer/logic/actionComponentMap/webserver/webserverOpenApiSpecActionComponentMap.js +0 -6
  31. package/lib/esm/LogViewer/logic/actionComponentMap/webserver/webserverOpenApiSpecActionComponentMap.js.map +0 -1
@@ -8,11 +8,10 @@ const webserverApiKeyValidationActionComponentMap_1 = __importDefault(require(".
8
8
  const webserverDnsActionComponentMap_1 = __importDefault(require("./webserverDnsActionComponentMap"));
9
9
  const webserverEmailActionComponentMap_1 = __importDefault(require("./webserverEmailActionComponentMap"));
10
10
  const webserverGenericDataResourceActionComponentMap_1 = __importDefault(require("./webserverGenericDataResourceActionComponentMap"));
11
- const webserverOpenApiSpecActionComponentMap_1 = __importDefault(require("./webserverOpenApiSpecActionComponentMap"));
12
11
  const webserverRouteAuthValidationActionComponentMap_1 = __importDefault(require("./webserverRouteAuthValidationActionComponentMap"));
13
12
  const webserverServiceActionComponentMap_1 = __importDefault(require("./webserverServiceActionComponentMap"));
14
13
  const webserverServiceFunctionActionComponentMap_1 = __importDefault(require("./webserverServiceFunctionActionComponentMap"));
15
14
  const webserverWebEntryActionComponentMap_1 = __importDefault(require("./webserverWebEntryActionComponentMap"));
16
15
  const webserverWebsocketActionComponentMap_1 = __importDefault(require("./webserverWebsocketActionComponentMap"));
17
- exports.default = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, webserverAdminActionComponentMap_1.default), webserverApiKeyValidationActionComponentMap_1.default), webserverDnsActionComponentMap_1.default), webserverEmailActionComponentMap_1.default), webserverGenericDataResourceActionComponentMap_1.default), webserverOpenApiSpecActionComponentMap_1.default), webserverRouteAuthValidationActionComponentMap_1.default), webserverServiceActionComponentMap_1.default), webserverServiceFunctionActionComponentMap_1.default), webserverWebEntryActionComponentMap_1.default), webserverWebsocketActionComponentMap_1.default);
16
+ exports.default = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, webserverAdminActionComponentMap_1.default), webserverApiKeyValidationActionComponentMap_1.default), webserverDnsActionComponentMap_1.default), webserverEmailActionComponentMap_1.default), webserverGenericDataResourceActionComponentMap_1.default), webserverRouteAuthValidationActionComponentMap_1.default), webserverServiceActionComponentMap_1.default), webserverServiceFunctionActionComponentMap_1.default), webserverWebEntryActionComponentMap_1.default), webserverWebsocketActionComponentMap_1.default);
18
17
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../src/LogViewer/logic/actionComponentMap/webserver/index.ts"],"names":[],"mappings":";;;;;AAAA,0GAAkF;AAClF,gIAAwG;AACxG,sGAA8E;AAC9E,0GAAkF;AAClF,sIAA8G;AAC9G,sHAA8F;AAC9F,sIAA8G;AAC9G,8GAAsF;AACtF,8HAAsG;AACtG,gHAAwF;AACxF,kHAA0F;AAE1F,gLACK,0CAAgC,GAChC,qDAA2C,GAC3C,wCAA8B,GAC9B,0CAAgC,GAChC,wDAA8C,GAC9C,gDAAsC,GACtC,wDAA8C,GAC9C,4CAAkC,GAClC,oDAA0C,GAC1C,6CAAmC,GACnC,8CAAoC,EACvC","sourcesContent":["import webserverAdminActionComponentMap from './webserverAdminActionComponentMap';\nimport webserverApiKeyValidationActionComponentMap from './webserverApiKeyValidationActionComponentMap';\nimport webserverDnsActionComponentMap from './webserverDnsActionComponentMap';\nimport webserverEmailActionComponentMap from './webserverEmailActionComponentMap';\nimport webserverGenericDataResourceActionComponentMap from './webserverGenericDataResourceActionComponentMap';\nimport webserverOpenApiSpecActionComponentMap from './webserverOpenApiSpecActionComponentMap';\nimport webserverRouteAuthValidationActionComponentMap from './webserverRouteAuthValidationActionComponentMap';\nimport webserverServiceActionComponentMap from './webserverServiceActionComponentMap';\nimport webserverServiceFunctionActionComponentMap from './webserverServiceFunctionActionComponentMap';\nimport webserverWebEntryActionComponentMap from './webserverWebEntryActionComponentMap';\nimport webserverWebsocketActionComponentMap from './webserverWebsocketActionComponentMap';\n\nexport default {\n ...webserverAdminActionComponentMap,\n ...webserverApiKeyValidationActionComponentMap,\n ...webserverDnsActionComponentMap,\n ...webserverEmailActionComponentMap,\n ...webserverGenericDataResourceActionComponentMap,\n ...webserverOpenApiSpecActionComponentMap,\n ...webserverRouteAuthValidationActionComponentMap,\n ...webserverServiceActionComponentMap,\n ...webserverServiceFunctionActionComponentMap,\n ...webserverWebEntryActionComponentMap,\n ...webserverWebsocketActionComponentMap,\n};\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../src/LogViewer/logic/actionComponentMap/webserver/index.ts"],"names":[],"mappings":";;;;;AAAA,0GAAkF;AAClF,gIAAwG;AACxG,sGAA8E;AAC9E,0GAAkF;AAClF,sIAA8G;AAC9G,sIAA8G;AAC9G,8GAAsF;AACtF,8HAAsG;AACtG,gHAAwF;AACxF,kHAA0F;AAE1F,kKACK,0CAAgC,GAChC,qDAA2C,GAC3C,wCAA8B,GAC9B,0CAAgC,GAChC,wDAA8C,GAC9C,wDAA8C,GAC9C,4CAAkC,GAClC,oDAA0C,GAC1C,6CAAmC,GACnC,8CAAoC,EACvC","sourcesContent":["import webserverAdminActionComponentMap from './webserverAdminActionComponentMap';\nimport webserverApiKeyValidationActionComponentMap from './webserverApiKeyValidationActionComponentMap';\nimport webserverDnsActionComponentMap from './webserverDnsActionComponentMap';\nimport webserverEmailActionComponentMap from './webserverEmailActionComponentMap';\nimport webserverGenericDataResourceActionComponentMap from './webserverGenericDataResourceActionComponentMap';\nimport webserverRouteAuthValidationActionComponentMap from './webserverRouteAuthValidationActionComponentMap';\nimport webserverServiceActionComponentMap from './webserverServiceActionComponentMap';\nimport webserverServiceFunctionActionComponentMap from './webserverServiceFunctionActionComponentMap';\nimport webserverWebEntryActionComponentMap from './webserverWebEntryActionComponentMap';\nimport webserverWebsocketActionComponentMap from './webserverWebsocketActionComponentMap';\n\nexport default {\n ...webserverAdminActionComponentMap,\n ...webserverApiKeyValidationActionComponentMap,\n ...webserverDnsActionComponentMap,\n ...webserverEmailActionComponentMap,\n ...webserverGenericDataResourceActionComponentMap,\n ...webserverRouteAuthValidationActionComponentMap,\n ...webserverServiceActionComponentMap,\n ...webserverServiceFunctionActionComponentMap,\n ...webserverWebEntryActionComponentMap,\n ...webserverWebsocketActionComponentMap,\n};\n"]}
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const quidproquo_webserver_1 = require("quidproquo-webserver");
4
4
  const webserverDnsActionComponentMap = {
5
5
  [quidproquo_webserver_1.DnsActionType.List]: ['askDnsList'],
6
+ [quidproquo_webserver_1.DnsActionType.ResolveHosts]: ['askDnsResolveHosts'],
6
7
  };
7
8
  exports.default = webserverDnsActionComponentMap;
8
9
  //# sourceMappingURL=webserverDnsActionComponentMap.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"webserverDnsActionComponentMap.js","sourceRoot":"","sources":["../../../../../../src/LogViewer/logic/actionComponentMap/webserver/webserverDnsActionComponentMap.ts"],"names":[],"mappings":";;AAAA,+DAAiE;AAEjE,MAAM,8BAA8B,GAA6B;IAC/D,CAAC,oCAAa,CAAC,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC;CACrC,CAAC;AAEF,kBAAe,8BAA8B,CAAC","sourcesContent":["import { askDnsList, DnsActionType } from 'quidproquo-webserver';\n\nconst webserverDnsActionComponentMap: Record<string, string[]> = {\n [DnsActionType.List]: ['askDnsList'],\n};\n\nexport default webserverDnsActionComponentMap;\n"]}
1
+ {"version":3,"file":"webserverDnsActionComponentMap.js","sourceRoot":"","sources":["../../../../../../src/LogViewer/logic/actionComponentMap/webserver/webserverDnsActionComponentMap.ts"],"names":[],"mappings":";;AAAA,+DAAqD;AAErD,MAAM,8BAA8B,GAA6B;IAC/D,CAAC,oCAAa,CAAC,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC;IACpC,CAAC,oCAAa,CAAC,YAAY,CAAC,EAAE,CAAC,oBAAoB,CAAC;CACrD,CAAC;AAEF,kBAAe,8BAA8B,CAAC","sourcesContent":["import { DnsActionType } from 'quidproquo-webserver';\n\nconst webserverDnsActionComponentMap: Record<string, string[]> = {\n [DnsActionType.List]: ['askDnsList'],\n [DnsActionType.ResolveHosts]: ['askDnsResolveHosts'],\n};\n\nexport default webserverDnsActionComponentMap;\n"]}
@@ -11,8 +11,6 @@ const localSessionEventActor_1 = require("../constants/localSessionEventActor");
11
11
  // processors with the action's PAYLOAD, so that is what this story receives.
12
12
  function* askApplySessionEventToLog(payload) {
13
13
  const clientMessageId = yield* (0, quidproquo_core_1.askNewGuid)();
14
- // Sortable ids need no allocator, so the id is minted here rather than positioned later.
15
- const eventId = yield* (0, quidproquo_core_1.askNewSortableGuid)();
16
14
  const createdAt = yield* (0, quidproquo_core_1.askDateNow)();
17
15
  const event = {
18
16
  type: payload.type,
@@ -23,7 +21,7 @@ function* askApplySessionEventToLog(payload) {
23
21
  clientMessageId,
24
22
  createdBy: localSessionEventActor_1.localSessionEventActor,
25
23
  createdAt,
26
- eventId,
24
+ eventId: 0,
27
25
  },
28
26
  },
29
27
  };
@@ -1 +1 @@
1
- {"version":3,"file":"askApplySessionEventToLog.js","sourceRoot":"","sources":["../../../../src/adminApp/actions/askApplySessionEventToLog.ts"],"names":[],"mappings":";;AAYA,8DAqBC;AAjCD,qDAA0F;AAG1F,4GAAyG;AACzG,sFAAmF;AACnF,gFAA6E;AAG7E,2EAA2E;AAC3E,8EAA8E;AAC9E,4EAA4E;AAC5E,6EAA6E;AAC7E,QAAe,CAAC,CAAC,yBAAyB,CAAC,OAAuC;IAChF,MAAM,eAAe,GAAG,KAAK,CAAC,CAAC,IAAA,4BAAU,GAAE,CAAC;IAC5C,yFAAyF;IACzF,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,IAAA,oCAAkB,GAAE,CAAC;IAC5C,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,IAAA,4BAAU,GAAE,CAAC;IAEtC,MAAM,KAAK,GAAkB;QAC3B,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,OAAO,EAAE;YACP,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,QAAQ,EAAE;gBACR,OAAO,EAAE,qDAAyB;gBAClC,eAAe;gBACf,SAAS,EAAE,+CAAsB;gBACjC,SAAS;gBACT,OAAO;aACR;SACF;KACF,CAAC;IAEF,KAAK,CAAC,CAAC,IAAA,2DAA4B,EAAC,KAAK,CAAC,CAAC;AAC7C,CAAC","sourcesContent":["import { askDateNow, askNewGuid, askNewSortableGuid, AskResponse } from 'quidproquo-core';\nimport { EventDocEvent } from 'quidproquo-features';\n\nimport { askUISessionLogEventAppended } from '../actionCreators/sessionLog/askUISessionLogEventAppended';\nimport { adminSessionSchemaVersion } from '../constants/adminSessionSchemaVersion';\nimport { localSessionEventActor } from '../constants/localSessionEventActor';\nimport { ApplySessionEventActionPayload } from './askApplySessionEvent';\n\n// The seam between pure yield and the event log: stamps local metadata and\n// appends optimistically (index assignment + coalescing live in the reducer);\n// the flush loop drains it to the backend. NOTE: the runtime invokes action\n// processors with the action's PAYLOAD, so that is what this story receives.\nexport function* askApplySessionEventToLog(payload: ApplySessionEventActionPayload): AskResponse<void> {\n const clientMessageId = yield* askNewGuid();\n // Sortable ids need no allocator, so the id is minted here rather than positioned later.\n const eventId = yield* askNewSortableGuid();\n const createdAt = yield* askDateNow();\n\n const event: EventDocEvent = {\n type: payload.type,\n payload: {\n data: payload.data,\n metadata: {\n version: adminSessionSchemaVersion,\n clientMessageId,\n createdBy: localSessionEventActor,\n createdAt,\n eventId,\n },\n },\n };\n\n yield* askUISessionLogEventAppended(event);\n}\n"]}
1
+ {"version":3,"file":"askApplySessionEventToLog.js","sourceRoot":"","sources":["../../../../src/adminApp/actions/askApplySessionEventToLog.ts"],"names":[],"mappings":";;AAYA,8DAmBC;AA/BD,qDAAsE;AAGtE,4GAAyG;AACzG,sFAAmF;AACnF,gFAA6E;AAG7E,2EAA2E;AAC3E,8EAA8E;AAC9E,4EAA4E;AAC5E,6EAA6E;AAC7E,QAAe,CAAC,CAAC,yBAAyB,CAAC,OAAuC;IAChF,MAAM,eAAe,GAAG,KAAK,CAAC,CAAC,IAAA,4BAAU,GAAE,CAAC;IAC5C,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,IAAA,4BAAU,GAAE,CAAC;IAEtC,MAAM,KAAK,GAAkB;QAC3B,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,OAAO,EAAE;YACP,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,QAAQ,EAAE;gBACR,OAAO,EAAE,qDAAyB;gBAClC,eAAe;gBACf,SAAS,EAAE,+CAAsB;gBACjC,SAAS;gBACT,OAAO,EAAE,CAAC;aACX;SACF;KACF,CAAC;IAEF,KAAK,CAAC,CAAC,IAAA,2DAA4B,EAAC,KAAK,CAAC,CAAC;AAC7C,CAAC","sourcesContent":["import { askDateNow, askNewGuid, AskResponse } from 'quidproquo-core';\nimport { EventDocEvent } from 'quidproquo-features';\n\nimport { askUISessionLogEventAppended } from '../actionCreators/sessionLog/askUISessionLogEventAppended';\nimport { adminSessionSchemaVersion } from '../constants/adminSessionSchemaVersion';\nimport { localSessionEventActor } from '../constants/localSessionEventActor';\nimport { ApplySessionEventActionPayload } from './askApplySessionEvent';\n\n// The seam between pure yield and the event log: stamps local metadata and\n// appends optimistically (index assignment + coalescing live in the reducer);\n// the flush loop drains it to the backend. NOTE: the runtime invokes action\n// processors with the action's PAYLOAD, so that is what this story receives.\nexport function* askApplySessionEventToLog(payload: ApplySessionEventActionPayload): AskResponse<void> {\n const clientMessageId = yield* askNewGuid();\n const createdAt = yield* askDateNow();\n\n const event: EventDocEvent = {\n type: payload.type,\n payload: {\n data: payload.data,\n metadata: {\n version: adminSessionSchemaVersion,\n clientMessageId,\n createdBy: localSessionEventActor,\n createdAt,\n eventId: 0,\n },\n },\n };\n\n yield* askUISessionLogEventAppended(event);\n}\n"]}
@@ -2,6 +2,13 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.eventAppended = void 0;
4
4
  const coalesceEventTypes_1 = require("../../constants/coalesceEventTypes");
5
+ // Event ids are contiguous positions in the log, so an optimistic append has to
6
+ // guess the next one: head + 1, or 0 for the first event of a fresh doc.
7
+ const nextLocalEventId = (state) => {
8
+ var _a;
9
+ const tail = (_a = state.pendingEvents[state.pendingEvents.length - 1]) !== null && _a !== void 0 ? _a : state.events[state.events.length - 1];
10
+ return tail ? tail.payload.metadata.eventId + 1 : 0;
11
+ };
5
12
  // Optimistic append with coalescing: while the previous event of the same
6
13
  // coalescable type is still pending, the new one replaces it (latest value
7
14
  // wins). The head is never coalesced while the flush has it in flight — the
@@ -12,14 +19,13 @@ const eventAppended = (state, event) => {
12
19
  const shouldCoalesce = !!last && !lastIsInFlightHead && last.type === event.type && coalesceEventTypes_1.coalesceEventTypes.includes(event.type);
13
20
  if (shouldCoalesce) {
14
21
  const coalesced = Object.assign(Object.assign({}, event), { payload: Object.assign(Object.assign({}, event.payload), {
15
- // Keeps the replaced event's id, so the coalesced event holds its place in the log
16
- // rather than jumping to the end.
22
+ // Takes over the replaced event's position rather than claiming a new one, so
23
+ // coalescing does not leave a hole in the contiguous log.
17
24
  metadata: Object.assign(Object.assign({}, event.payload.metadata), { eventId: last.payload.metadata.eventId }) }) });
18
25
  return Object.assign(Object.assign({}, state), { pendingEvents: [...state.pendingEvents.slice(0, -1), coalesced] });
19
26
  }
20
- // The event already carries the id minted when it was created, and sortable ids order
21
- // themselves, so there is nothing to assign here.
22
- return Object.assign(Object.assign({}, state), { pendingEvents: [...state.pendingEvents, event] });
27
+ const appended = Object.assign(Object.assign({}, event), { payload: Object.assign(Object.assign({}, event.payload), { metadata: Object.assign(Object.assign({}, event.payload.metadata), { eventId: nextLocalEventId(state) }) }) });
28
+ return Object.assign(Object.assign({}, state), { pendingEvents: [...state.pendingEvents, appended] });
23
29
  };
24
30
  exports.eventAppended = eventAppended;
25
31
  //# sourceMappingURL=eventAppended.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"eventAppended.js","sourceRoot":"","sources":["../../../../../src/adminApp/stateUpdaters/sessionLog/eventAppended.ts"],"names":[],"mappings":";;;AAEA,2EAAwE;AAIxE,0EAA0E;AAC1E,2EAA2E;AAC3E,4EAA4E;AAC5E,+DAA+D;AACxD,MAAM,aAAa,GAAG,CAAC,KAAsB,EAAE,KAAoB,EAAmB,EAAE;IAC7F,MAAM,IAAI,GAAG,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAEjE,MAAM,kBAAkB,GAAG,KAAK,CAAC,aAAa,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC;IACpF,MAAM,cAAc,GAClB,CAAC,CAAC,IAAI,IAAI,CAAC,kBAAkB,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,IAAI,uCAAkB,CAAC,QAAQ,CAAC,KAAK,CAAC,IAA6B,CAAC,CAAC;IAEhI,IAAI,cAAc,EAAE,CAAC;QACnB,MAAM,SAAS,mCACV,KAAK,KACR,OAAO,kCACF,KAAK,CAAC,OAAO;gBAChB,mFAAmF;gBACnF,kCAAkC;gBAClC,QAAQ,kCAAO,KAAK,CAAC,OAAO,CAAC,QAAQ,KAAE,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,SAEhF,CAAC;QAEF,uCACK,KAAK,KACR,aAAa,EAAE,CAAC,GAAG,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,IAC/D;IACJ,CAAC;IAED,sFAAsF;IACtF,kDAAkD;IAClD,uCACK,KAAK,KACR,aAAa,EAAE,CAAC,GAAG,KAAK,CAAC,aAAa,EAAE,KAAK,CAAC,IAC9C;AACJ,CAAC,CAAC;AA9BW,QAAA,aAAa,iBA8BxB","sourcesContent":["import { EventDocEvent } from 'quidproquo-features';\n\nimport { coalesceEventTypes } from '../../constants/coalesceEventTypes';\nimport { AdminSessionEventType } from '../../effects/session/AdminSessionEventType';\nimport { SessionLogState } from '../../SessionLogState';\n\n// Optimistic append with coalescing: while the previous event of the same\n// coalescable type is still pending, the new one replaces it (latest value\n// wins). The head is never coalesced while the flush has it in flight — the\n// POSTed clientMessageId must stay matchable for the save ack.\nexport const eventAppended = (state: SessionLogState, event: EventDocEvent): SessionLogState => {\n const last = state.pendingEvents[state.pendingEvents.length - 1];\n\n const lastIsInFlightHead = state.pendingEvents.length === 1 && state.flush.inFlight;\n const shouldCoalesce =\n !!last && !lastIsInFlightHead && last.type === event.type && coalesceEventTypes.includes(event.type as AdminSessionEventType);\n\n if (shouldCoalesce) {\n const coalesced: EventDocEvent = {\n ...event,\n payload: {\n ...event.payload,\n // Keeps the replaced event's id, so the coalesced event holds its place in the log\n // rather than jumping to the end.\n metadata: { ...event.payload.metadata, eventId: last.payload.metadata.eventId },\n },\n };\n\n return {\n ...state,\n pendingEvents: [...state.pendingEvents.slice(0, -1), coalesced],\n };\n }\n\n // The event already carries the id minted when it was created, and sortable ids order\n // themselves, so there is nothing to assign here.\n return {\n ...state,\n pendingEvents: [...state.pendingEvents, event],\n };\n};\n"]}
1
+ {"version":3,"file":"eventAppended.js","sourceRoot":"","sources":["../../../../../src/adminApp/stateUpdaters/sessionLog/eventAppended.ts"],"names":[],"mappings":";;;AAEA,2EAAwE;AAIxE,gFAAgF;AAChF,yEAAyE;AACzE,MAAM,gBAAgB,GAAG,CAAC,KAAsB,EAAU,EAAE;;IAC1D,MAAM,IAAI,GAAG,MAAA,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,mCAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC1G,OAAO,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACtD,CAAC,CAAC;AAEF,0EAA0E;AAC1E,2EAA2E;AAC3E,4EAA4E;AAC5E,+DAA+D;AACxD,MAAM,aAAa,GAAG,CAAC,KAAsB,EAAE,KAAoB,EAAmB,EAAE;IAC7F,MAAM,IAAI,GAAG,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAEjE,MAAM,kBAAkB,GAAG,KAAK,CAAC,aAAa,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC;IACpF,MAAM,cAAc,GAClB,CAAC,CAAC,IAAI,IAAI,CAAC,kBAAkB,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,IAAI,uCAAkB,CAAC,QAAQ,CAAC,KAAK,CAAC,IAA6B,CAAC,CAAC;IAEhI,IAAI,cAAc,EAAE,CAAC;QACnB,MAAM,SAAS,mCACV,KAAK,KACR,OAAO,kCACF,KAAK,CAAC,OAAO;gBAChB,8EAA8E;gBAC9E,0DAA0D;gBAC1D,QAAQ,kCAAO,KAAK,CAAC,OAAO,CAAC,QAAQ,KAAE,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,SAEhF,CAAC;QAEF,uCACK,KAAK,KACR,aAAa,EAAE,CAAC,GAAG,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,IAC/D;IACJ,CAAC;IAED,MAAM,QAAQ,mCACT,KAAK,KACR,OAAO,kCACF,KAAK,CAAC,OAAO,KAChB,QAAQ,kCAAO,KAAK,CAAC,OAAO,CAAC,QAAQ,KAAE,OAAO,EAAE,gBAAgB,CAAC,KAAK,CAAC,SAE1E,CAAC;IAEF,uCACK,KAAK,KACR,aAAa,EAAE,CAAC,GAAG,KAAK,CAAC,aAAa,EAAE,QAAQ,CAAC,IACjD;AACJ,CAAC,CAAC;AApCW,QAAA,aAAa,iBAoCxB","sourcesContent":["import { EventDocEvent } from 'quidproquo-features';\n\nimport { coalesceEventTypes } from '../../constants/coalesceEventTypes';\nimport { AdminSessionEventType } from '../../effects/session/AdminSessionEventType';\nimport { SessionLogState } from '../../SessionLogState';\n\n// Event ids are contiguous positions in the log, so an optimistic append has to\n// guess the next one: head + 1, or 0 for the first event of a fresh doc.\nconst nextLocalEventId = (state: SessionLogState): number => {\n const tail = state.pendingEvents[state.pendingEvents.length - 1] ?? state.events[state.events.length - 1];\n return tail ? tail.payload.metadata.eventId + 1 : 0;\n};\n\n// Optimistic append with coalescing: while the previous event of the same\n// coalescable type is still pending, the new one replaces it (latest value\n// wins). The head is never coalesced while the flush has it in flight — the\n// POSTed clientMessageId must stay matchable for the save ack.\nexport const eventAppended = (state: SessionLogState, event: EventDocEvent): SessionLogState => {\n const last = state.pendingEvents[state.pendingEvents.length - 1];\n\n const lastIsInFlightHead = state.pendingEvents.length === 1 && state.flush.inFlight;\n const shouldCoalesce =\n !!last && !lastIsInFlightHead && last.type === event.type && coalesceEventTypes.includes(event.type as AdminSessionEventType);\n\n if (shouldCoalesce) {\n const coalesced: EventDocEvent = {\n ...event,\n payload: {\n ...event.payload,\n // Takes over the replaced event's position rather than claiming a new one, so\n // coalescing does not leave a hole in the contiguous log.\n metadata: { ...event.payload.metadata, eventId: last.payload.metadata.eventId },\n },\n };\n\n return {\n ...state,\n pendingEvents: [...state.pendingEvents.slice(0, -1), coalesced],\n };\n }\n\n const appended: EventDocEvent = {\n ...event,\n payload: {\n ...event.payload,\n metadata: { ...event.payload.metadata, eventId: nextLocalEventId(state) },\n },\n };\n\n return {\n ...state,\n pendingEvents: [...state.pendingEvents, appended],\n };\n};\n"]}
@@ -2,14 +2,13 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.eventSaved = void 0;
4
4
  // Server ack: the pending event moves to the acked log with its server-stamped
5
- // metadata, and the remaining pending events renumber onto consecutive indexes
6
- // after it (the server may have assigned a later index than our optimistic one).
5
+ // metadata, and the remaining pending events renumber onto consecutive event ids
6
+ // after it (the server may have assigned a later position than our optimistic one).
7
7
  const eventSaved = (state, payload) => {
8
8
  const savedAt = state.pendingEvents.findIndex((event) => event.payload.metadata.clientMessageId === payload.clientMessageId);
9
9
  const remaining = savedAt === -1 ? state.pendingEvents : [...state.pendingEvents.slice(0, savedAt), ...state.pendingEvents.slice(savedAt + 1)];
10
- // No renumbering: each pending event minted its own sortable id, which already sorts after
11
- // the saved log. Removing one from the middle leaves the rest correctly ordered.
12
- return Object.assign(Object.assign({}, state), { events: [...state.events, payload.storedEvent], pendingEvents: remaining, flush: { inFlight: false, lastError: null, retryCount: 0 } });
10
+ const renumbered = remaining.map((event, offset) => (Object.assign(Object.assign({}, event), { payload: Object.assign(Object.assign({}, event.payload), { metadata: Object.assign(Object.assign({}, event.payload.metadata), { eventId: payload.storedEvent.payload.metadata.eventId + 1 + offset }) }) })));
11
+ return Object.assign(Object.assign({}, state), { events: [...state.events, payload.storedEvent], pendingEvents: renumbered, flush: { inFlight: false, lastError: null, retryCount: 0 } });
13
12
  };
14
13
  exports.eventSaved = eventSaved;
15
14
  //# sourceMappingURL=eventSaved.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"eventSaved.js","sourceRoot":"","sources":["../../../../../src/adminApp/stateUpdaters/sessionLog/eventSaved.ts"],"names":[],"mappings":";;;AAKA,+EAA+E;AAC/E,+EAA+E;AAC/E,iFAAiF;AAC1E,MAAM,UAAU,GAAG,CAAC,KAAsB,EAAE,OAAoC,EAAmB,EAAE;IAC1G,MAAM,OAAO,GAAG,KAAK,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,eAAe,KAAK,OAAO,CAAC,eAAe,CAAC,CAAC;IAE7H,MAAM,SAAS,GAAG,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,GAAG,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC;IAE/I,2FAA2F;IAC3F,iFAAiF;IACjF,uCACK,KAAK,KACR,MAAM,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC,WAAW,CAAC,EAC9C,aAAa,EAAE,SAAS,EACxB,KAAK,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,EAAE,IAC1D;AACJ,CAAC,CAAC;AAbW,QAAA,UAAU,cAarB","sourcesContent":["import { EventDocEvent } from 'quidproquo-features';\n\nimport { SessionLogEventSavedPayload } from '../../effects/sessionLog/SessionLogEventSavedEffect';\nimport { SessionLogState } from '../../SessionLogState';\n\n// Server ack: the pending event moves to the acked log with its server-stamped\n// metadata, and the remaining pending events renumber onto consecutive indexes\n// after it (the server may have assigned a later index than our optimistic one).\nexport const eventSaved = (state: SessionLogState, payload: SessionLogEventSavedPayload): SessionLogState => {\n const savedAt = state.pendingEvents.findIndex((event) => event.payload.metadata.clientMessageId === payload.clientMessageId);\n\n const remaining = savedAt === -1 ? state.pendingEvents : [...state.pendingEvents.slice(0, savedAt), ...state.pendingEvents.slice(savedAt + 1)];\n\n // No renumbering: each pending event minted its own sortable id, which already sorts after\n // the saved log. Removing one from the middle leaves the rest correctly ordered.\n return {\n ...state,\n events: [...state.events, payload.storedEvent],\n pendingEvents: remaining,\n flush: { inFlight: false, lastError: null, retryCount: 0 },\n };\n};\n"]}
1
+ {"version":3,"file":"eventSaved.js","sourceRoot":"","sources":["../../../../../src/adminApp/stateUpdaters/sessionLog/eventSaved.ts"],"names":[],"mappings":";;;AAKA,+EAA+E;AAC/E,iFAAiF;AACjF,oFAAoF;AAC7E,MAAM,UAAU,GAAG,CAAC,KAAsB,EAAE,OAAoC,EAAmB,EAAE;IAC1G,MAAM,OAAO,GAAG,KAAK,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,eAAe,KAAK,OAAO,CAAC,eAAe,CAAC,CAAC;IAE7H,MAAM,SAAS,GAAG,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,GAAG,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC;IAE/I,MAAM,UAAU,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,EAAiB,EAAE,CAAC,iCAC9D,KAAK,KACR,OAAO,kCACF,KAAK,CAAC,OAAO,KAChB,QAAQ,kCAAO,KAAK,CAAC,OAAO,CAAC,QAAQ,KAAE,OAAO,EAAE,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,GAAG,CAAC,GAAG,MAAM,UAE3G,CAAC,CAAC;IAEJ,uCACK,KAAK,KACR,MAAM,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC,WAAW,CAAC,EAC9C,aAAa,EAAE,UAAU,EACzB,KAAK,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,EAAE,IAC1D;AACJ,CAAC,CAAC;AAnBW,QAAA,UAAU,cAmBrB","sourcesContent":["import { EventDocEvent } from 'quidproquo-features';\n\nimport { SessionLogEventSavedPayload } from '../../effects/sessionLog/SessionLogEventSavedEffect';\nimport { SessionLogState } from '../../SessionLogState';\n\n// Server ack: the pending event moves to the acked log with its server-stamped\n// metadata, and the remaining pending events renumber onto consecutive event ids\n// after it (the server may have assigned a later position than our optimistic one).\nexport const eventSaved = (state: SessionLogState, payload: SessionLogEventSavedPayload): SessionLogState => {\n const savedAt = state.pendingEvents.findIndex((event) => event.payload.metadata.clientMessageId === payload.clientMessageId);\n\n const remaining = savedAt === -1 ? state.pendingEvents : [...state.pendingEvents.slice(0, savedAt), ...state.pendingEvents.slice(savedAt + 1)];\n\n const renumbered = remaining.map((event, offset): EventDocEvent => ({\n ...event,\n payload: {\n ...event.payload,\n metadata: { ...event.payload.metadata, eventId: payload.storedEvent.payload.metadata.eventId + 1 + offset },\n },\n }));\n\n return {\n ...state,\n events: [...state.events, payload.storedEvent],\n pendingEvents: renumbered,\n flush: { inFlight: false, lastError: null, retryCount: 0 },\n };\n};\n"]}
@@ -15,8 +15,7 @@ const makeSessionEvent = (type, data, index, overrides) => {
15
15
  clientMessageId: (_a = overrides === null || overrides === void 0 ? void 0 : overrides.clientMessageId) !== null && _a !== void 0 ? _a : `cmid-${index}`,
16
16
  createdBy: { userId: 'test-user', userDisplayName: 'Test User' },
17
17
  createdAt: (_b = overrides === null || overrides === void 0 ? void 0 : overrides.createdAt) !== null && _b !== void 0 ? _b : `2026-07-07T00:00:0${Math.min(index, 9)}.000Z`,
18
- // Padded so the stub ids sort in creation order, like real sortable ids.
19
- eventId: String(index).padStart(4, '0'),
18
+ eventId: index,
20
19
  },
21
20
  },
22
21
  });
@@ -1 +1 @@
1
- {"version":3,"file":"makeSessionEvent.js","sourceRoot":"","sources":["../../../../src/adminApp/testHelpers/makeSessionEvent.ts"],"names":[],"mappings":";;;AACA,6DAAoE;AAEpE,sFAAmF;AAEnF,oEAAoE;AAC7D,MAAM,gBAAgB,GAAG,CAC9B,IAAY,EACZ,IAAO,EACP,KAAa,EACb,SAAoE,EACrD,EAAE;;IAAC,OAAA,CAAC;QACnB,IAAI;QACJ,OAAO,EAAE;YACP,IAAI;YACJ,QAAQ,EAAE;gBACR,OAAO,EAAE,qDAAyB;gBAClC,eAAe,EAAE,MAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,eAAe,mCAAI,QAAQ,KAAK,EAAE;gBAC9D,SAAS,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,eAAe,EAAE,WAAW,EAAE;gBAChE,SAAS,EAAE,MAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,SAAS,mCAAK,qBAAqB,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,OAA0B;gBACrG,yEAAyE;gBACzE,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC;aACxC;SACF;KACF,CAAC,CAAA;CAAA,CAAC;AAlBU,QAAA,gBAAgB,oBAkB1B;AAEI,MAAM,kBAAkB,GAAG,CAAC,EAAU,EAAE,IAAY,EAAiB,EAAE,CAC5E,IAAA,wBAAgB,EAAC,oCAAc,CAAC,SAAS,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;AADvE,QAAA,kBAAkB,sBACqD","sourcesContent":["import { QpqIsoDateTime } from 'quidproquo-core';\nimport { EventDocEffect, EventDocEvent } from 'quidproquo-features';\n\nimport { adminSessionSchemaVersion } from '../constants/adminSessionSchemaVersion';\n\n// Builds a session event with sensible metadata defaults for tests.\nexport const makeSessionEvent = <T>(\n type: string,\n data: T,\n index: number,\n overrides?: { clientMessageId?: string; createdAt?: QpqIsoDateTime },\n): EventDocEvent => ({\n type,\n payload: {\n data,\n metadata: {\n version: adminSessionSchemaVersion,\n clientMessageId: overrides?.clientMessageId ?? `cmid-${index}`,\n createdBy: { userId: 'test-user', userDisplayName: 'Test User' },\n createdAt: overrides?.createdAt ?? (`2026-07-07T00:00:0${Math.min(index, 9)}.000Z` as QpqIsoDateTime),\n // Padded so the stub ids sort in creation order, like real sortable ids.\n eventId: String(index).padStart(4, '0'),\n },\n },\n});\n\nexport const makeInitStateEvent = (id: string, name: string): EventDocEvent =>\n makeSessionEvent(EventDocEffect.InitState, { id, code: 'session-code', name }, 0);\n"]}
1
+ {"version":3,"file":"makeSessionEvent.js","sourceRoot":"","sources":["../../../../src/adminApp/testHelpers/makeSessionEvent.ts"],"names":[],"mappings":";;;AACA,6DAAoE;AAEpE,sFAAmF;AAEnF,oEAAoE;AAC7D,MAAM,gBAAgB,GAAG,CAC9B,IAAY,EACZ,IAAO,EACP,KAAa,EACb,SAAoE,EACrD,EAAE;;IAAC,OAAA,CAAC;QACnB,IAAI;QACJ,OAAO,EAAE;YACP,IAAI;YACJ,QAAQ,EAAE;gBACR,OAAO,EAAE,qDAAyB;gBAClC,eAAe,EAAE,MAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,eAAe,mCAAI,QAAQ,KAAK,EAAE;gBAC9D,SAAS,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,eAAe,EAAE,WAAW,EAAE;gBAChE,SAAS,EAAE,MAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,SAAS,mCAAK,qBAAqB,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,OAA0B;gBACrG,OAAO,EAAE,KAAK;aACf;SACF;KACF,CAAC,CAAA;CAAA,CAAC;AAjBU,QAAA,gBAAgB,oBAiB1B;AAEI,MAAM,kBAAkB,GAAG,CAAC,EAAU,EAAE,IAAY,EAAiB,EAAE,CAC5E,IAAA,wBAAgB,EAAC,oCAAc,CAAC,SAAS,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;AADvE,QAAA,kBAAkB,sBACqD","sourcesContent":["import { QpqIsoDateTime } from 'quidproquo-core';\nimport { EventDocEffect, EventDocEvent } from 'quidproquo-features';\n\nimport { adminSessionSchemaVersion } from '../constants/adminSessionSchemaVersion';\n\n// Builds a session event with sensible metadata defaults for tests.\nexport const makeSessionEvent = <T>(\n type: string,\n data: T,\n index: number,\n overrides?: { clientMessageId?: string; createdAt?: QpqIsoDateTime },\n): EventDocEvent => ({\n type,\n payload: {\n data,\n metadata: {\n version: adminSessionSchemaVersion,\n clientMessageId: overrides?.clientMessageId ?? `cmid-${index}`,\n createdBy: { userId: 'test-user', userDisplayName: 'Test User' },\n createdAt: overrides?.createdAt ?? (`2026-07-07T00:00:0${Math.min(index, 9)}.000Z` as QpqIsoDateTime),\n eventId: index,\n },\n },\n});\n\nexport const makeInitStateEvent = (id: string, name: string): EventDocEvent =>\n makeSessionEvent(EventDocEffect.InitState, { id, code: 'session-code', name }, 0);\n"]}
@@ -3,7 +3,6 @@ import webserverApiKeyValidationActionComponentMap from './webserverApiKeyValida
3
3
  import webserverDnsActionComponentMap from './webserverDnsActionComponentMap';
4
4
  import webserverEmailActionComponentMap from './webserverEmailActionComponentMap';
5
5
  import webserverGenericDataResourceActionComponentMap from './webserverGenericDataResourceActionComponentMap';
6
- import webserverOpenApiSpecActionComponentMap from './webserverOpenApiSpecActionComponentMap';
7
6
  import webserverRouteAuthValidationActionComponentMap from './webserverRouteAuthValidationActionComponentMap';
8
7
  import webserverServiceActionComponentMap from './webserverServiceActionComponentMap';
9
8
  import webserverServiceFunctionActionComponentMap from './webserverServiceFunctionActionComponentMap';
@@ -15,7 +14,6 @@ export default {
15
14
  ...webserverDnsActionComponentMap,
16
15
  ...webserverEmailActionComponentMap,
17
16
  ...webserverGenericDataResourceActionComponentMap,
18
- ...webserverOpenApiSpecActionComponentMap,
19
17
  ...webserverRouteAuthValidationActionComponentMap,
20
18
  ...webserverServiceActionComponentMap,
21
19
  ...webserverServiceFunctionActionComponentMap,
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../src/LogViewer/logic/actionComponentMap/webserver/index.ts"],"names":[],"mappings":"AAAA,OAAO,gCAAgC,MAAM,oCAAoC,CAAC;AAClF,OAAO,2CAA2C,MAAM,+CAA+C,CAAC;AACxG,OAAO,8BAA8B,MAAM,kCAAkC,CAAC;AAC9E,OAAO,gCAAgC,MAAM,oCAAoC,CAAC;AAClF,OAAO,8CAA8C,MAAM,kDAAkD,CAAC;AAC9G,OAAO,sCAAsC,MAAM,0CAA0C,CAAC;AAC9F,OAAO,8CAA8C,MAAM,kDAAkD,CAAC;AAC9G,OAAO,kCAAkC,MAAM,sCAAsC,CAAC;AACtF,OAAO,0CAA0C,MAAM,8CAA8C,CAAC;AACtG,OAAO,mCAAmC,MAAM,uCAAuC,CAAC;AACxF,OAAO,oCAAoC,MAAM,wCAAwC,CAAC;AAE1F,eAAe;IACb,GAAG,gCAAgC;IACnC,GAAG,2CAA2C;IAC9C,GAAG,8BAA8B;IACjC,GAAG,gCAAgC;IACnC,GAAG,8CAA8C;IACjD,GAAG,sCAAsC;IACzC,GAAG,8CAA8C;IACjD,GAAG,kCAAkC;IACrC,GAAG,0CAA0C;IAC7C,GAAG,mCAAmC;IACtC,GAAG,oCAAoC;CACxC,CAAC","sourcesContent":["import webserverAdminActionComponentMap from './webserverAdminActionComponentMap';\nimport webserverApiKeyValidationActionComponentMap from './webserverApiKeyValidationActionComponentMap';\nimport webserverDnsActionComponentMap from './webserverDnsActionComponentMap';\nimport webserverEmailActionComponentMap from './webserverEmailActionComponentMap';\nimport webserverGenericDataResourceActionComponentMap from './webserverGenericDataResourceActionComponentMap';\nimport webserverOpenApiSpecActionComponentMap from './webserverOpenApiSpecActionComponentMap';\nimport webserverRouteAuthValidationActionComponentMap from './webserverRouteAuthValidationActionComponentMap';\nimport webserverServiceActionComponentMap from './webserverServiceActionComponentMap';\nimport webserverServiceFunctionActionComponentMap from './webserverServiceFunctionActionComponentMap';\nimport webserverWebEntryActionComponentMap from './webserverWebEntryActionComponentMap';\nimport webserverWebsocketActionComponentMap from './webserverWebsocketActionComponentMap';\n\nexport default {\n ...webserverAdminActionComponentMap,\n ...webserverApiKeyValidationActionComponentMap,\n ...webserverDnsActionComponentMap,\n ...webserverEmailActionComponentMap,\n ...webserverGenericDataResourceActionComponentMap,\n ...webserverOpenApiSpecActionComponentMap,\n ...webserverRouteAuthValidationActionComponentMap,\n ...webserverServiceActionComponentMap,\n ...webserverServiceFunctionActionComponentMap,\n ...webserverWebEntryActionComponentMap,\n ...webserverWebsocketActionComponentMap,\n};\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../src/LogViewer/logic/actionComponentMap/webserver/index.ts"],"names":[],"mappings":"AAAA,OAAO,gCAAgC,MAAM,oCAAoC,CAAC;AAClF,OAAO,2CAA2C,MAAM,+CAA+C,CAAC;AACxG,OAAO,8BAA8B,MAAM,kCAAkC,CAAC;AAC9E,OAAO,gCAAgC,MAAM,oCAAoC,CAAC;AAClF,OAAO,8CAA8C,MAAM,kDAAkD,CAAC;AAC9G,OAAO,8CAA8C,MAAM,kDAAkD,CAAC;AAC9G,OAAO,kCAAkC,MAAM,sCAAsC,CAAC;AACtF,OAAO,0CAA0C,MAAM,8CAA8C,CAAC;AACtG,OAAO,mCAAmC,MAAM,uCAAuC,CAAC;AACxF,OAAO,oCAAoC,MAAM,wCAAwC,CAAC;AAE1F,eAAe;IACb,GAAG,gCAAgC;IACnC,GAAG,2CAA2C;IAC9C,GAAG,8BAA8B;IACjC,GAAG,gCAAgC;IACnC,GAAG,8CAA8C;IACjD,GAAG,8CAA8C;IACjD,GAAG,kCAAkC;IACrC,GAAG,0CAA0C;IAC7C,GAAG,mCAAmC;IACtC,GAAG,oCAAoC;CACxC,CAAC","sourcesContent":["import webserverAdminActionComponentMap from './webserverAdminActionComponentMap';\nimport webserverApiKeyValidationActionComponentMap from './webserverApiKeyValidationActionComponentMap';\nimport webserverDnsActionComponentMap from './webserverDnsActionComponentMap';\nimport webserverEmailActionComponentMap from './webserverEmailActionComponentMap';\nimport webserverGenericDataResourceActionComponentMap from './webserverGenericDataResourceActionComponentMap';\nimport webserverRouteAuthValidationActionComponentMap from './webserverRouteAuthValidationActionComponentMap';\nimport webserverServiceActionComponentMap from './webserverServiceActionComponentMap';\nimport webserverServiceFunctionActionComponentMap from './webserverServiceFunctionActionComponentMap';\nimport webserverWebEntryActionComponentMap from './webserverWebEntryActionComponentMap';\nimport webserverWebsocketActionComponentMap from './webserverWebsocketActionComponentMap';\n\nexport default {\n ...webserverAdminActionComponentMap,\n ...webserverApiKeyValidationActionComponentMap,\n ...webserverDnsActionComponentMap,\n ...webserverEmailActionComponentMap,\n ...webserverGenericDataResourceActionComponentMap,\n ...webserverRouteAuthValidationActionComponentMap,\n ...webserverServiceActionComponentMap,\n ...webserverServiceFunctionActionComponentMap,\n ...webserverWebEntryActionComponentMap,\n ...webserverWebsocketActionComponentMap,\n};\n"]}
@@ -1,6 +1,7 @@
1
1
  import { DnsActionType } from 'quidproquo-webserver';
2
2
  const webserverDnsActionComponentMap = {
3
3
  [DnsActionType.List]: ['askDnsList'],
4
+ [DnsActionType.ResolveHosts]: ['askDnsResolveHosts'],
4
5
  };
5
6
  export default webserverDnsActionComponentMap;
6
7
  //# sourceMappingURL=webserverDnsActionComponentMap.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"webserverDnsActionComponentMap.js","sourceRoot":"","sources":["../../../../../../src/LogViewer/logic/actionComponentMap/webserver/webserverDnsActionComponentMap.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAEjE,MAAM,8BAA8B,GAA6B;IAC/D,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC;CACrC,CAAC;AAEF,eAAe,8BAA8B,CAAC","sourcesContent":["import { askDnsList, DnsActionType } from 'quidproquo-webserver';\n\nconst webserverDnsActionComponentMap: Record<string, string[]> = {\n [DnsActionType.List]: ['askDnsList'],\n};\n\nexport default webserverDnsActionComponentMap;\n"]}
1
+ {"version":3,"file":"webserverDnsActionComponentMap.js","sourceRoot":"","sources":["../../../../../../src/LogViewer/logic/actionComponentMap/webserver/webserverDnsActionComponentMap.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,MAAM,8BAA8B,GAA6B;IAC/D,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC;IACpC,CAAC,aAAa,CAAC,YAAY,CAAC,EAAE,CAAC,oBAAoB,CAAC;CACrD,CAAC;AAEF,eAAe,8BAA8B,CAAC","sourcesContent":["import { DnsActionType } from 'quidproquo-webserver';\n\nconst webserverDnsActionComponentMap: Record<string, string[]> = {\n [DnsActionType.List]: ['askDnsList'],\n [DnsActionType.ResolveHosts]: ['askDnsResolveHosts'],\n};\n\nexport default webserverDnsActionComponentMap;\n"]}
@@ -1,4 +1,4 @@
1
- import { askDateNow, askNewGuid, askNewSortableGuid } from 'quidproquo-core';
1
+ import { askDateNow, askNewGuid } from 'quidproquo-core';
2
2
  import { askUISessionLogEventAppended } from '../actionCreators/sessionLog/askUISessionLogEventAppended';
3
3
  import { adminSessionSchemaVersion } from '../constants/adminSessionSchemaVersion';
4
4
  import { localSessionEventActor } from '../constants/localSessionEventActor';
@@ -8,8 +8,6 @@ import { localSessionEventActor } from '../constants/localSessionEventActor';
8
8
  // processors with the action's PAYLOAD, so that is what this story receives.
9
9
  export function* askApplySessionEventToLog(payload) {
10
10
  const clientMessageId = yield* askNewGuid();
11
- // Sortable ids need no allocator, so the id is minted here rather than positioned later.
12
- const eventId = yield* askNewSortableGuid();
13
11
  const createdAt = yield* askDateNow();
14
12
  const event = {
15
13
  type: payload.type,
@@ -20,7 +18,7 @@ export function* askApplySessionEventToLog(payload) {
20
18
  clientMessageId,
21
19
  createdBy: localSessionEventActor,
22
20
  createdAt,
23
- eventId,
21
+ eventId: 0,
24
22
  },
25
23
  },
26
24
  };
@@ -1 +1 @@
1
- {"version":3,"file":"askApplySessionEventToLog.js","sourceRoot":"","sources":["../../../../src/adminApp/actions/askApplySessionEventToLog.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,kBAAkB,EAAe,MAAM,iBAAiB,CAAC;AAG1F,OAAO,EAAE,4BAA4B,EAAE,MAAM,2DAA2D,CAAC;AACzG,OAAO,EAAE,yBAAyB,EAAE,MAAM,wCAAwC,CAAC;AACnF,OAAO,EAAE,sBAAsB,EAAE,MAAM,qCAAqC,CAAC;AAG7E,2EAA2E;AAC3E,8EAA8E;AAC9E,4EAA4E;AAC5E,6EAA6E;AAC7E,MAAM,SAAS,CAAC,CAAC,yBAAyB,CAAC,OAAuC;IAChF,MAAM,eAAe,GAAG,KAAK,CAAC,CAAC,UAAU,EAAE,CAAC;IAC5C,yFAAyF;IACzF,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,kBAAkB,EAAE,CAAC;IAC5C,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,UAAU,EAAE,CAAC;IAEtC,MAAM,KAAK,GAAkB;QAC3B,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,OAAO,EAAE;YACP,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,QAAQ,EAAE;gBACR,OAAO,EAAE,yBAAyB;gBAClC,eAAe;gBACf,SAAS,EAAE,sBAAsB;gBACjC,SAAS;gBACT,OAAO;aACR;SACF;KACF,CAAC;IAEF,KAAK,CAAC,CAAC,4BAA4B,CAAC,KAAK,CAAC,CAAC;AAC7C,CAAC","sourcesContent":["import { askDateNow, askNewGuid, askNewSortableGuid, AskResponse } from 'quidproquo-core';\nimport { EventDocEvent } from 'quidproquo-features';\n\nimport { askUISessionLogEventAppended } from '../actionCreators/sessionLog/askUISessionLogEventAppended';\nimport { adminSessionSchemaVersion } from '../constants/adminSessionSchemaVersion';\nimport { localSessionEventActor } from '../constants/localSessionEventActor';\nimport { ApplySessionEventActionPayload } from './askApplySessionEvent';\n\n// The seam between pure yield and the event log: stamps local metadata and\n// appends optimistically (index assignment + coalescing live in the reducer);\n// the flush loop drains it to the backend. NOTE: the runtime invokes action\n// processors with the action's PAYLOAD, so that is what this story receives.\nexport function* askApplySessionEventToLog(payload: ApplySessionEventActionPayload): AskResponse<void> {\n const clientMessageId = yield* askNewGuid();\n // Sortable ids need no allocator, so the id is minted here rather than positioned later.\n const eventId = yield* askNewSortableGuid();\n const createdAt = yield* askDateNow();\n\n const event: EventDocEvent = {\n type: payload.type,\n payload: {\n data: payload.data,\n metadata: {\n version: adminSessionSchemaVersion,\n clientMessageId,\n createdBy: localSessionEventActor,\n createdAt,\n eventId,\n },\n },\n };\n\n yield* askUISessionLogEventAppended(event);\n}\n"]}
1
+ {"version":3,"file":"askApplySessionEventToLog.js","sourceRoot":"","sources":["../../../../src/adminApp/actions/askApplySessionEventToLog.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAe,MAAM,iBAAiB,CAAC;AAGtE,OAAO,EAAE,4BAA4B,EAAE,MAAM,2DAA2D,CAAC;AACzG,OAAO,EAAE,yBAAyB,EAAE,MAAM,wCAAwC,CAAC;AACnF,OAAO,EAAE,sBAAsB,EAAE,MAAM,qCAAqC,CAAC;AAG7E,2EAA2E;AAC3E,8EAA8E;AAC9E,4EAA4E;AAC5E,6EAA6E;AAC7E,MAAM,SAAS,CAAC,CAAC,yBAAyB,CAAC,OAAuC;IAChF,MAAM,eAAe,GAAG,KAAK,CAAC,CAAC,UAAU,EAAE,CAAC;IAC5C,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,UAAU,EAAE,CAAC;IAEtC,MAAM,KAAK,GAAkB;QAC3B,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,OAAO,EAAE;YACP,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,QAAQ,EAAE;gBACR,OAAO,EAAE,yBAAyB;gBAClC,eAAe;gBACf,SAAS,EAAE,sBAAsB;gBACjC,SAAS;gBACT,OAAO,EAAE,CAAC;aACX;SACF;KACF,CAAC;IAEF,KAAK,CAAC,CAAC,4BAA4B,CAAC,KAAK,CAAC,CAAC;AAC7C,CAAC","sourcesContent":["import { askDateNow, askNewGuid, AskResponse } from 'quidproquo-core';\nimport { EventDocEvent } from 'quidproquo-features';\n\nimport { askUISessionLogEventAppended } from '../actionCreators/sessionLog/askUISessionLogEventAppended';\nimport { adminSessionSchemaVersion } from '../constants/adminSessionSchemaVersion';\nimport { localSessionEventActor } from '../constants/localSessionEventActor';\nimport { ApplySessionEventActionPayload } from './askApplySessionEvent';\n\n// The seam between pure yield and the event log: stamps local metadata and\n// appends optimistically (index assignment + coalescing live in the reducer);\n// the flush loop drains it to the backend. NOTE: the runtime invokes action\n// processors with the action's PAYLOAD, so that is what this story receives.\nexport function* askApplySessionEventToLog(payload: ApplySessionEventActionPayload): AskResponse<void> {\n const clientMessageId = yield* askNewGuid();\n const createdAt = yield* askDateNow();\n\n const event: EventDocEvent = {\n type: payload.type,\n payload: {\n data: payload.data,\n metadata: {\n version: adminSessionSchemaVersion,\n clientMessageId,\n createdBy: localSessionEventActor,\n createdAt,\n eventId: 0,\n },\n },\n };\n\n yield* askUISessionLogEventAppended(event);\n}\n"]}
@@ -1,4 +1,10 @@
1
1
  import { coalesceEventTypes } from '../../constants/coalesceEventTypes';
2
+ // Event ids are contiguous positions in the log, so an optimistic append has to
3
+ // guess the next one: head + 1, or 0 for the first event of a fresh doc.
4
+ const nextLocalEventId = (state) => {
5
+ const tail = state.pendingEvents[state.pendingEvents.length - 1] ?? state.events[state.events.length - 1];
6
+ return tail ? tail.payload.metadata.eventId + 1 : 0;
7
+ };
2
8
  // Optimistic append with coalescing: while the previous event of the same
3
9
  // coalescable type is still pending, the new one replaces it (latest value
4
10
  // wins). The head is never coalesced while the flush has it in flight — the
@@ -12,8 +18,8 @@ export const eventAppended = (state, event) => {
12
18
  ...event,
13
19
  payload: {
14
20
  ...event.payload,
15
- // Keeps the replaced event's id, so the coalesced event holds its place in the log
16
- // rather than jumping to the end.
21
+ // Takes over the replaced event's position rather than claiming a new one, so
22
+ // coalescing does not leave a hole in the contiguous log.
17
23
  metadata: { ...event.payload.metadata, eventId: last.payload.metadata.eventId },
18
24
  },
19
25
  };
@@ -22,11 +28,16 @@ export const eventAppended = (state, event) => {
22
28
  pendingEvents: [...state.pendingEvents.slice(0, -1), coalesced],
23
29
  };
24
30
  }
25
- // The event already carries the id minted when it was created, and sortable ids order
26
- // themselves, so there is nothing to assign here.
31
+ const appended = {
32
+ ...event,
33
+ payload: {
34
+ ...event.payload,
35
+ metadata: { ...event.payload.metadata, eventId: nextLocalEventId(state) },
36
+ },
37
+ };
27
38
  return {
28
39
  ...state,
29
- pendingEvents: [...state.pendingEvents, event],
40
+ pendingEvents: [...state.pendingEvents, appended],
30
41
  };
31
42
  };
32
43
  //# sourceMappingURL=eventAppended.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"eventAppended.js","sourceRoot":"","sources":["../../../../../src/adminApp/stateUpdaters/sessionLog/eventAppended.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AAIxE,0EAA0E;AAC1E,2EAA2E;AAC3E,4EAA4E;AAC5E,+DAA+D;AAC/D,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,KAAsB,EAAE,KAAoB,EAAmB,EAAE;IAC7F,MAAM,IAAI,GAAG,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAEjE,MAAM,kBAAkB,GAAG,KAAK,CAAC,aAAa,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC;IACpF,MAAM,cAAc,GAClB,CAAC,CAAC,IAAI,IAAI,CAAC,kBAAkB,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,IAAI,kBAAkB,CAAC,QAAQ,CAAC,KAAK,CAAC,IAA6B,CAAC,CAAC;IAEhI,IAAI,cAAc,EAAE,CAAC;QACnB,MAAM,SAAS,GAAkB;YAC/B,GAAG,KAAK;YACR,OAAO,EAAE;gBACP,GAAG,KAAK,CAAC,OAAO;gBAChB,mFAAmF;gBACnF,kCAAkC;gBAClC,QAAQ,EAAE,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,EAAE;aAChF;SACF,CAAC;QAEF,OAAO;YACL,GAAG,KAAK;YACR,aAAa,EAAE,CAAC,GAAG,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC;SAChE,CAAC;IACJ,CAAC;IAED,sFAAsF;IACtF,kDAAkD;IAClD,OAAO;QACL,GAAG,KAAK;QACR,aAAa,EAAE,CAAC,GAAG,KAAK,CAAC,aAAa,EAAE,KAAK,CAAC;KAC/C,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import { EventDocEvent } from 'quidproquo-features';\n\nimport { coalesceEventTypes } from '../../constants/coalesceEventTypes';\nimport { AdminSessionEventType } from '../../effects/session/AdminSessionEventType';\nimport { SessionLogState } from '../../SessionLogState';\n\n// Optimistic append with coalescing: while the previous event of the same\n// coalescable type is still pending, the new one replaces it (latest value\n// wins). The head is never coalesced while the flush has it in flight — the\n// POSTed clientMessageId must stay matchable for the save ack.\nexport const eventAppended = (state: SessionLogState, event: EventDocEvent): SessionLogState => {\n const last = state.pendingEvents[state.pendingEvents.length - 1];\n\n const lastIsInFlightHead = state.pendingEvents.length === 1 && state.flush.inFlight;\n const shouldCoalesce =\n !!last && !lastIsInFlightHead && last.type === event.type && coalesceEventTypes.includes(event.type as AdminSessionEventType);\n\n if (shouldCoalesce) {\n const coalesced: EventDocEvent = {\n ...event,\n payload: {\n ...event.payload,\n // Keeps the replaced event's id, so the coalesced event holds its place in the log\n // rather than jumping to the end.\n metadata: { ...event.payload.metadata, eventId: last.payload.metadata.eventId },\n },\n };\n\n return {\n ...state,\n pendingEvents: [...state.pendingEvents.slice(0, -1), coalesced],\n };\n }\n\n // The event already carries the id minted when it was created, and sortable ids order\n // themselves, so there is nothing to assign here.\n return {\n ...state,\n pendingEvents: [...state.pendingEvents, event],\n };\n};\n"]}
1
+ {"version":3,"file":"eventAppended.js","sourceRoot":"","sources":["../../../../../src/adminApp/stateUpdaters/sessionLog/eventAppended.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AAIxE,gFAAgF;AAChF,yEAAyE;AACzE,MAAM,gBAAgB,GAAG,CAAC,KAAsB,EAAU,EAAE;IAC1D,MAAM,IAAI,GAAG,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC1G,OAAO,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACtD,CAAC,CAAC;AAEF,0EAA0E;AAC1E,2EAA2E;AAC3E,4EAA4E;AAC5E,+DAA+D;AAC/D,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,KAAsB,EAAE,KAAoB,EAAmB,EAAE;IAC7F,MAAM,IAAI,GAAG,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAEjE,MAAM,kBAAkB,GAAG,KAAK,CAAC,aAAa,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC;IACpF,MAAM,cAAc,GAClB,CAAC,CAAC,IAAI,IAAI,CAAC,kBAAkB,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,IAAI,kBAAkB,CAAC,QAAQ,CAAC,KAAK,CAAC,IAA6B,CAAC,CAAC;IAEhI,IAAI,cAAc,EAAE,CAAC;QACnB,MAAM,SAAS,GAAkB;YAC/B,GAAG,KAAK;YACR,OAAO,EAAE;gBACP,GAAG,KAAK,CAAC,OAAO;gBAChB,8EAA8E;gBAC9E,0DAA0D;gBAC1D,QAAQ,EAAE,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,EAAE;aAChF;SACF,CAAC;QAEF,OAAO;YACL,GAAG,KAAK;YACR,aAAa,EAAE,CAAC,GAAG,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC;SAChE,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAkB;QAC9B,GAAG,KAAK;QACR,OAAO,EAAE;YACP,GAAG,KAAK,CAAC,OAAO;YAChB,QAAQ,EAAE,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,EAAE,gBAAgB,CAAC,KAAK,CAAC,EAAE;SAC1E;KACF,CAAC;IAEF,OAAO;QACL,GAAG,KAAK;QACR,aAAa,EAAE,CAAC,GAAG,KAAK,CAAC,aAAa,EAAE,QAAQ,CAAC;KAClD,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import { EventDocEvent } from 'quidproquo-features';\n\nimport { coalesceEventTypes } from '../../constants/coalesceEventTypes';\nimport { AdminSessionEventType } from '../../effects/session/AdminSessionEventType';\nimport { SessionLogState } from '../../SessionLogState';\n\n// Event ids are contiguous positions in the log, so an optimistic append has to\n// guess the next one: head + 1, or 0 for the first event of a fresh doc.\nconst nextLocalEventId = (state: SessionLogState): number => {\n const tail = state.pendingEvents[state.pendingEvents.length - 1] ?? state.events[state.events.length - 1];\n return tail ? tail.payload.metadata.eventId + 1 : 0;\n};\n\n// Optimistic append with coalescing: while the previous event of the same\n// coalescable type is still pending, the new one replaces it (latest value\n// wins). The head is never coalesced while the flush has it in flight — the\n// POSTed clientMessageId must stay matchable for the save ack.\nexport const eventAppended = (state: SessionLogState, event: EventDocEvent): SessionLogState => {\n const last = state.pendingEvents[state.pendingEvents.length - 1];\n\n const lastIsInFlightHead = state.pendingEvents.length === 1 && state.flush.inFlight;\n const shouldCoalesce =\n !!last && !lastIsInFlightHead && last.type === event.type && coalesceEventTypes.includes(event.type as AdminSessionEventType);\n\n if (shouldCoalesce) {\n const coalesced: EventDocEvent = {\n ...event,\n payload: {\n ...event.payload,\n // Takes over the replaced event's position rather than claiming a new one, so\n // coalescing does not leave a hole in the contiguous log.\n metadata: { ...event.payload.metadata, eventId: last.payload.metadata.eventId },\n },\n };\n\n return {\n ...state,\n pendingEvents: [...state.pendingEvents.slice(0, -1), coalesced],\n };\n }\n\n const appended: EventDocEvent = {\n ...event,\n payload: {\n ...event.payload,\n metadata: { ...event.payload.metadata, eventId: nextLocalEventId(state) },\n },\n };\n\n return {\n ...state,\n pendingEvents: [...state.pendingEvents, appended],\n };\n};\n"]}
@@ -1,15 +1,20 @@
1
1
  // Server ack: the pending event moves to the acked log with its server-stamped
2
- // metadata, and the remaining pending events renumber onto consecutive indexes
3
- // after it (the server may have assigned a later index than our optimistic one).
2
+ // metadata, and the remaining pending events renumber onto consecutive event ids
3
+ // after it (the server may have assigned a later position than our optimistic one).
4
4
  export const eventSaved = (state, payload) => {
5
5
  const savedAt = state.pendingEvents.findIndex((event) => event.payload.metadata.clientMessageId === payload.clientMessageId);
6
6
  const remaining = savedAt === -1 ? state.pendingEvents : [...state.pendingEvents.slice(0, savedAt), ...state.pendingEvents.slice(savedAt + 1)];
7
- // No renumbering: each pending event minted its own sortable id, which already sorts after
8
- // the saved log. Removing one from the middle leaves the rest correctly ordered.
7
+ const renumbered = remaining.map((event, offset) => ({
8
+ ...event,
9
+ payload: {
10
+ ...event.payload,
11
+ metadata: { ...event.payload.metadata, eventId: payload.storedEvent.payload.metadata.eventId + 1 + offset },
12
+ },
13
+ }));
9
14
  return {
10
15
  ...state,
11
16
  events: [...state.events, payload.storedEvent],
12
- pendingEvents: remaining,
17
+ pendingEvents: renumbered,
13
18
  flush: { inFlight: false, lastError: null, retryCount: 0 },
14
19
  };
15
20
  };
@@ -1 +1 @@
1
- {"version":3,"file":"eventSaved.js","sourceRoot":"","sources":["../../../../../src/adminApp/stateUpdaters/sessionLog/eventSaved.ts"],"names":[],"mappings":"AAKA,+EAA+E;AAC/E,+EAA+E;AAC/E,iFAAiF;AACjF,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,KAAsB,EAAE,OAAoC,EAAmB,EAAE;IAC1G,MAAM,OAAO,GAAG,KAAK,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,eAAe,KAAK,OAAO,CAAC,eAAe,CAAC,CAAC;IAE7H,MAAM,SAAS,GAAG,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,GAAG,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC;IAE/I,2FAA2F;IAC3F,iFAAiF;IACjF,OAAO;QACL,GAAG,KAAK;QACR,MAAM,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC,WAAW,CAAC;QAC9C,aAAa,EAAE,SAAS;QACxB,KAAK,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,EAAE;KAC3D,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import { EventDocEvent } from 'quidproquo-features';\n\nimport { SessionLogEventSavedPayload } from '../../effects/sessionLog/SessionLogEventSavedEffect';\nimport { SessionLogState } from '../../SessionLogState';\n\n// Server ack: the pending event moves to the acked log with its server-stamped\n// metadata, and the remaining pending events renumber onto consecutive indexes\n// after it (the server may have assigned a later index than our optimistic one).\nexport const eventSaved = (state: SessionLogState, payload: SessionLogEventSavedPayload): SessionLogState => {\n const savedAt = state.pendingEvents.findIndex((event) => event.payload.metadata.clientMessageId === payload.clientMessageId);\n\n const remaining = savedAt === -1 ? state.pendingEvents : [...state.pendingEvents.slice(0, savedAt), ...state.pendingEvents.slice(savedAt + 1)];\n\n // No renumbering: each pending event minted its own sortable id, which already sorts after\n // the saved log. Removing one from the middle leaves the rest correctly ordered.\n return {\n ...state,\n events: [...state.events, payload.storedEvent],\n pendingEvents: remaining,\n flush: { inFlight: false, lastError: null, retryCount: 0 },\n };\n};\n"]}
1
+ {"version":3,"file":"eventSaved.js","sourceRoot":"","sources":["../../../../../src/adminApp/stateUpdaters/sessionLog/eventSaved.ts"],"names":[],"mappings":"AAKA,+EAA+E;AAC/E,iFAAiF;AACjF,oFAAoF;AACpF,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,KAAsB,EAAE,OAAoC,EAAmB,EAAE;IAC1G,MAAM,OAAO,GAAG,KAAK,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,eAAe,KAAK,OAAO,CAAC,eAAe,CAAC,CAAC;IAE7H,MAAM,SAAS,GAAG,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,GAAG,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC;IAE/I,MAAM,UAAU,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,EAAiB,EAAE,CAAC,CAAC;QAClE,GAAG,KAAK;QACR,OAAO,EAAE;YACP,GAAG,KAAK,CAAC,OAAO;YAChB,QAAQ,EAAE,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,GAAG,CAAC,GAAG,MAAM,EAAE;SAC5G;KACF,CAAC,CAAC,CAAC;IAEJ,OAAO;QACL,GAAG,KAAK;QACR,MAAM,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC,WAAW,CAAC;QAC9C,aAAa,EAAE,UAAU;QACzB,KAAK,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,EAAE;KAC3D,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import { EventDocEvent } from 'quidproquo-features';\n\nimport { SessionLogEventSavedPayload } from '../../effects/sessionLog/SessionLogEventSavedEffect';\nimport { SessionLogState } from '../../SessionLogState';\n\n// Server ack: the pending event moves to the acked log with its server-stamped\n// metadata, and the remaining pending events renumber onto consecutive event ids\n// after it (the server may have assigned a later position than our optimistic one).\nexport const eventSaved = (state: SessionLogState, payload: SessionLogEventSavedPayload): SessionLogState => {\n const savedAt = state.pendingEvents.findIndex((event) => event.payload.metadata.clientMessageId === payload.clientMessageId);\n\n const remaining = savedAt === -1 ? state.pendingEvents : [...state.pendingEvents.slice(0, savedAt), ...state.pendingEvents.slice(savedAt + 1)];\n\n const renumbered = remaining.map((event, offset): EventDocEvent => ({\n ...event,\n payload: {\n ...event.payload,\n metadata: { ...event.payload.metadata, eventId: payload.storedEvent.payload.metadata.eventId + 1 + offset },\n },\n }));\n\n return {\n ...state,\n events: [...state.events, payload.storedEvent],\n pendingEvents: renumbered,\n flush: { inFlight: false, lastError: null, retryCount: 0 },\n };\n};\n"]}
@@ -10,8 +10,7 @@ export const makeSessionEvent = (type, data, index, overrides) => ({
10
10
  clientMessageId: overrides?.clientMessageId ?? `cmid-${index}`,
11
11
  createdBy: { userId: 'test-user', userDisplayName: 'Test User' },
12
12
  createdAt: overrides?.createdAt ?? `2026-07-07T00:00:0${Math.min(index, 9)}.000Z`,
13
- // Padded so the stub ids sort in creation order, like real sortable ids.
14
- eventId: String(index).padStart(4, '0'),
13
+ eventId: index,
15
14
  },
16
15
  },
17
16
  });
@@ -1 +1 @@
1
- {"version":3,"file":"makeSessionEvent.js","sourceRoot":"","sources":["../../../../src/adminApp/testHelpers/makeSessionEvent.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAiB,MAAM,qBAAqB,CAAC;AAEpE,OAAO,EAAE,yBAAyB,EAAE,MAAM,wCAAwC,CAAC;AAEnF,oEAAoE;AACpE,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC9B,IAAY,EACZ,IAAO,EACP,KAAa,EACb,SAAoE,EACrD,EAAE,CAAC,CAAC;IACnB,IAAI;IACJ,OAAO,EAAE;QACP,IAAI;QACJ,QAAQ,EAAE;YACR,OAAO,EAAE,yBAAyB;YAClC,eAAe,EAAE,SAAS,EAAE,eAAe,IAAI,QAAQ,KAAK,EAAE;YAC9D,SAAS,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,eAAe,EAAE,WAAW,EAAE;YAChE,SAAS,EAAE,SAAS,EAAE,SAAS,IAAK,qBAAqB,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,OAA0B;YACrG,yEAAyE;YACzE,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC;SACxC;KACF;CACF,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,EAAU,EAAE,IAAY,EAAiB,EAAE,CAC5E,gBAAgB,CAAC,cAAc,CAAC,SAAS,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC","sourcesContent":["import { QpqIsoDateTime } from 'quidproquo-core';\nimport { EventDocEffect, EventDocEvent } from 'quidproquo-features';\n\nimport { adminSessionSchemaVersion } from '../constants/adminSessionSchemaVersion';\n\n// Builds a session event with sensible metadata defaults for tests.\nexport const makeSessionEvent = <T>(\n type: string,\n data: T,\n index: number,\n overrides?: { clientMessageId?: string; createdAt?: QpqIsoDateTime },\n): EventDocEvent => ({\n type,\n payload: {\n data,\n metadata: {\n version: adminSessionSchemaVersion,\n clientMessageId: overrides?.clientMessageId ?? `cmid-${index}`,\n createdBy: { userId: 'test-user', userDisplayName: 'Test User' },\n createdAt: overrides?.createdAt ?? (`2026-07-07T00:00:0${Math.min(index, 9)}.000Z` as QpqIsoDateTime),\n // Padded so the stub ids sort in creation order, like real sortable ids.\n eventId: String(index).padStart(4, '0'),\n },\n },\n});\n\nexport const makeInitStateEvent = (id: string, name: string): EventDocEvent =>\n makeSessionEvent(EventDocEffect.InitState, { id, code: 'session-code', name }, 0);\n"]}
1
+ {"version":3,"file":"makeSessionEvent.js","sourceRoot":"","sources":["../../../../src/adminApp/testHelpers/makeSessionEvent.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAiB,MAAM,qBAAqB,CAAC;AAEpE,OAAO,EAAE,yBAAyB,EAAE,MAAM,wCAAwC,CAAC;AAEnF,oEAAoE;AACpE,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC9B,IAAY,EACZ,IAAO,EACP,KAAa,EACb,SAAoE,EACrD,EAAE,CAAC,CAAC;IACnB,IAAI;IACJ,OAAO,EAAE;QACP,IAAI;QACJ,QAAQ,EAAE;YACR,OAAO,EAAE,yBAAyB;YAClC,eAAe,EAAE,SAAS,EAAE,eAAe,IAAI,QAAQ,KAAK,EAAE;YAC9D,SAAS,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,eAAe,EAAE,WAAW,EAAE;YAChE,SAAS,EAAE,SAAS,EAAE,SAAS,IAAK,qBAAqB,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,OAA0B;YACrG,OAAO,EAAE,KAAK;SACf;KACF;CACF,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,EAAU,EAAE,IAAY,EAAiB,EAAE,CAC5E,gBAAgB,CAAC,cAAc,CAAC,SAAS,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC","sourcesContent":["import { QpqIsoDateTime } from 'quidproquo-core';\nimport { EventDocEffect, EventDocEvent } from 'quidproquo-features';\n\nimport { adminSessionSchemaVersion } from '../constants/adminSessionSchemaVersion';\n\n// Builds a session event with sensible metadata defaults for tests.\nexport const makeSessionEvent = <T>(\n type: string,\n data: T,\n index: number,\n overrides?: { clientMessageId?: string; createdAt?: QpqIsoDateTime },\n): EventDocEvent => ({\n type,\n payload: {\n data,\n metadata: {\n version: adminSessionSchemaVersion,\n clientMessageId: overrides?.clientMessageId ?? `cmid-${index}`,\n createdBy: { userId: 'test-user', userDisplayName: 'Test User' },\n createdAt: overrides?.createdAt ?? (`2026-07-07T00:00:0${Math.min(index, 9)}.000Z` as QpqIsoDateTime),\n eventId: index,\n },\n },\n});\n\nexport const makeInitStateEvent = (id: string, name: string): EventDocEvent =>\n makeSessionEvent(EventDocEffect.InitState, { id, code: 'session-code', name }, 0);\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "quidproquo-web-admin",
3
- "version": "0.1.18",
3
+ "version": "0.1.20",
4
4
  "description": "",
5
5
  "main": "./lib/commonjs/index.js",
6
6
  "module": "./lib/esm/index.js",
@@ -47,12 +47,12 @@
47
47
  "date-fns": "^2.30.0",
48
48
  "dayjs": "^1.11.7",
49
49
  "javascript-time-ago": "^2.5.9",
50
- "quidproquo-core": "0.1.18",
51
- "quidproquo-features": "0.1.18",
52
- "quidproquo-tsconfig": "0.1.18",
53
- "quidproquo-web": "0.1.18",
54
- "quidproquo-web-react": "0.1.18",
55
- "quidproquo-webserver": "0.1.18",
50
+ "quidproquo-core": "0.1.20",
51
+ "quidproquo-features": "0.1.20",
52
+ "quidproquo-tsconfig": "0.1.20",
53
+ "quidproquo-web": "0.1.20",
54
+ "quidproquo-web-react": "0.1.20",
55
+ "quidproquo-webserver": "0.1.20",
56
56
  "react": ">=18.3.1",
57
57
  "react-d3-tree": "^3.6.6",
58
58
  "react-dom": "18.3.1",
@@ -1,2 +0,0 @@
1
- declare const webserverOpenApiSpecActionComponentMap: Record<string, string[]>;
2
- export default webserverOpenApiSpecActionComponentMap;
@@ -1,8 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const quidproquo_webserver_1 = require("quidproquo-webserver");
4
- const webserverOpenApiSpecActionComponentMap = {
5
- [quidproquo_webserver_1.OpenApiSpecActionType.GetOpenApiSpec]: ['askGetOpenApiSpec'],
6
- };
7
- exports.default = webserverOpenApiSpecActionComponentMap;
8
- //# sourceMappingURL=webserverOpenApiSpecActionComponentMap.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"webserverOpenApiSpecActionComponentMap.js","sourceRoot":"","sources":["../../../../../../src/LogViewer/logic/actionComponentMap/webserver/webserverOpenApiSpecActionComponentMap.ts"],"names":[],"mappings":";;AAAA,+DAA6D;AAE7D,MAAM,sCAAsC,GAA6B;IACvE,CAAC,4CAAqB,CAAC,cAAc,CAAC,EAAE,CAAC,mBAAmB,CAAC;CAC9D,CAAC;AAEF,kBAAe,sCAAsC,CAAC","sourcesContent":["import { OpenApiSpecActionType } from 'quidproquo-webserver';\n\nconst webserverOpenApiSpecActionComponentMap: Record<string, string[]> = {\n [OpenApiSpecActionType.GetOpenApiSpec]: ['askGetOpenApiSpec'],\n};\n\nexport default webserverOpenApiSpecActionComponentMap;\n"]}
@@ -1,2 +0,0 @@
1
- declare const webserverOpenApiSpecActionComponentMap: Record<string, string[]>;
2
- export default webserverOpenApiSpecActionComponentMap;
@@ -1,6 +0,0 @@
1
- import { OpenApiSpecActionType } from 'quidproquo-webserver';
2
- const webserverOpenApiSpecActionComponentMap = {
3
- [OpenApiSpecActionType.GetOpenApiSpec]: ['askGetOpenApiSpec'],
4
- };
5
- export default webserverOpenApiSpecActionComponentMap;
6
- //# sourceMappingURL=webserverOpenApiSpecActionComponentMap.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"webserverOpenApiSpecActionComponentMap.js","sourceRoot":"","sources":["../../../../../../src/LogViewer/logic/actionComponentMap/webserver/webserverOpenApiSpecActionComponentMap.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAE7D,MAAM,sCAAsC,GAA6B;IACvE,CAAC,qBAAqB,CAAC,cAAc,CAAC,EAAE,CAAC,mBAAmB,CAAC;CAC9D,CAAC;AAEF,eAAe,sCAAsC,CAAC","sourcesContent":["import { OpenApiSpecActionType } from 'quidproquo-webserver';\n\nconst webserverOpenApiSpecActionComponentMap: Record<string, string[]> = {\n [OpenApiSpecActionType.GetOpenApiSpec]: ['askGetOpenApiSpec'],\n};\n\nexport default webserverOpenApiSpecActionComponentMap;\n"]}