@ferricstore/ferricstore 0.11.4 → 0.11.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -2716,7 +2716,7 @@ declare class WorkflowWorker {
2716
2716
  }
2717
2717
 
2718
2718
  /** TypeScript SDK package version. */
2719
- declare const FERRICSTORE_SDK_VERSION = "0.11.4";
2719
+ declare const FERRICSTORE_SDK_VERSION = "0.11.6";
2720
2720
  /** Oldest FerricStore server supported by this breaking beta contract. */
2721
2721
  declare const FERRICSTORE_MINIMUM_SERVER_VERSION = "0.11.4";
2722
2722
  /** Native framing and opcode ABI version; unchanged by FerricStore 0.11. */
package/dist/index.d.ts CHANGED
@@ -2716,7 +2716,7 @@ declare class WorkflowWorker {
2716
2716
  }
2717
2717
 
2718
2718
  /** TypeScript SDK package version. */
2719
- declare const FERRICSTORE_SDK_VERSION = "0.11.4";
2719
+ declare const FERRICSTORE_SDK_VERSION = "0.11.6";
2720
2720
  /** Oldest FerricStore server supported by this breaking beta contract. */
2721
2721
  declare const FERRICSTORE_MINIMUM_SERVER_VERSION = "0.11.4";
2722
2722
  /** Native framing and opcode ABI version; unchanged by FerricStore 0.11. */
package/dist/index.js CHANGED
@@ -4535,7 +4535,7 @@ function compactKeyPipelinePayload(opcode, args, mode, maxBodyBytes) {
4535
4535
  }
4536
4536
  return { flags: FLAG_CUSTOM_PAYLOAD, opcode, payload: out };
4537
4537
  }
4538
- function compactPipelinePayload(commands, maxBodyBytes) {
4538
+ function compactPipelinePayload(commands, maxBodyBytes, allowStreamXAdd = true, allowPubSubPublish = true) {
4539
4539
  if (commands.length === 0) {
4540
4540
  assertCompactPayloadFits(6, maxBodyBytes);
4541
4541
  const out = Buffer15.allocUnsafe(6);
@@ -4547,8 +4547,115 @@ function compactPipelinePayload(commands, maxBodyBytes) {
4547
4547
  }
4548
4548
  if (commandNameIs(commands[0]?.[0], "SET")) return compactSetPipelinePayload(commands, maxBodyBytes);
4549
4549
  if (commandNameIs(commands[0]?.[0], "GET")) return compactGetPipelinePayload(commands, maxBodyBytes);
4550
+ if (commandNameIs(commands[0]?.[0], "XADD")) {
4551
+ return allowStreamXAdd ? compactStreamXAddPipelinePayload(commands, maxBodyBytes) : void 0;
4552
+ }
4553
+ if (commandNameIs(commands[0]?.[0], "PUBLISH")) {
4554
+ return allowPubSubPublish ? compactPubSubPublishPipelinePayload(commands, maxBodyBytes) : void 0;
4555
+ }
4550
4556
  return void 0;
4551
4557
  }
4558
+ function compactPubSubPublishPipelinePayload(commands, maxBodyBytes) {
4559
+ const minimum = 6 + commands.length * 8;
4560
+ if (!compactPayloadFits(minimum, maxBodyBytes)) {
4561
+ if (!compactPipelineEligible(commands, "PUBLISH", 3)) return void 0;
4562
+ assertCompactPayloadFits(minimum, maxBodyBytes);
4563
+ }
4564
+ const argumentByteLengths = new Uint32Array(commands.length * 2);
4565
+ const argumentValues = new Array(commands.length * 2);
4566
+ let total = 6;
4567
+ for (let index = 0; index < commands.length; index += 1) {
4568
+ const command = commands[index];
4569
+ if (!Object.hasOwn(commands, index) || !Array.isArray(command)) {
4570
+ throw new TypeError("pipeline commands must be a dense array of command arrays");
4571
+ }
4572
+ if (command.length !== 3 || !Object.hasOwn(command, 0) || !Object.hasOwn(command, 1) || !Object.hasOwn(command, 2)) {
4573
+ if (command.length === 3) throw new TypeError("pipeline command arguments must be dense");
4574
+ return void 0;
4575
+ }
4576
+ if (!commandNameIs(command[0], "PUBLISH")) return void 0;
4577
+ const channel = command[1];
4578
+ const message = command[2];
4579
+ if (!isCompactBinaryScalar(channel) || !isCompactBinaryScalar(message)) return void 0;
4580
+ const channelByteLength = compactBinaryByteLength(channel);
4581
+ const messageByteLength = compactBinaryByteLength(message);
4582
+ argumentValues[index * 2] = channel;
4583
+ argumentValues[index * 2 + 1] = message;
4584
+ argumentByteLengths[index * 2] = channelByteLength;
4585
+ argumentByteLengths[index * 2 + 1] = messageByteLength;
4586
+ total += 8 + channelByteLength + messageByteLength;
4587
+ }
4588
+ assertCompactPayloadFits(total, maxBodyBytes);
4589
+ const out = Buffer15.allocUnsafe(total);
4590
+ let offset = writeCompactPipelineHeader(out, 128 | 35, commands.length);
4591
+ for (let index = 0; index < commands.length; index += 1) {
4592
+ offset = writeBinaryValue(
4593
+ out,
4594
+ offset,
4595
+ argumentValues[index * 2],
4596
+ argumentByteLengths[index * 2] ?? 0
4597
+ );
4598
+ offset = writeBinaryValue(
4599
+ out,
4600
+ offset,
4601
+ argumentValues[index * 2 + 1],
4602
+ argumentByteLengths[index * 2 + 1] ?? 0
4603
+ );
4604
+ }
4605
+ return out;
4606
+ }
4607
+ function compactStreamXAddPipelinePayload(commands, maxBodyBytes) {
4608
+ let argumentCount = 0;
4609
+ let minimum = 6;
4610
+ for (const command of commands) {
4611
+ if (!Array.isArray(command)) {
4612
+ throw new TypeError("pipeline commands must be a dense array of command arrays");
4613
+ }
4614
+ if (command.length < 5 || (command.length - 3) % 2 !== 0) return void 0;
4615
+ for (let argumentIndex = 0; argumentIndex < command.length; argumentIndex += 1) {
4616
+ if (!Object.hasOwn(command, argumentIndex)) {
4617
+ throw new TypeError("pipeline command arguments must be dense");
4618
+ }
4619
+ }
4620
+ if (!commandTokenIs(command[0], "XADD") || !commandTokenIs(command[2], "*")) return void 0;
4621
+ if ((command.length - 3) / 2 > 65535) return void 0;
4622
+ for (let argumentIndex = 1; argumentIndex < command.length; argumentIndex += 1) {
4623
+ if (argumentIndex !== 2 && !isCompactBinaryScalar(command[argumentIndex])) return void 0;
4624
+ }
4625
+ argumentCount += command.length - 2;
4626
+ minimum += 2 + (command.length - 2) * 4;
4627
+ }
4628
+ assertCompactPayloadFits(minimum, maxBodyBytes);
4629
+ const byteLengths = new Uint32Array(argumentCount);
4630
+ let lengthIndex = 0;
4631
+ let total = 6;
4632
+ for (const command of commands) {
4633
+ total += 2;
4634
+ for (let argumentIndex = 1; argumentIndex < command.length; argumentIndex += 1) {
4635
+ if (argumentIndex === 2) continue;
4636
+ const value = command[argumentIndex];
4637
+ const byteLength = compactBinaryByteLength(value);
4638
+ byteLengths[lengthIndex] = byteLength;
4639
+ lengthIndex += 1;
4640
+ total += 4 + byteLength;
4641
+ }
4642
+ }
4643
+ assertCompactPayloadFits(total, maxBodyBytes);
4644
+ const out = Buffer15.allocUnsafe(total);
4645
+ let offset = writeCompactPipelineHeader(out, 128 | 34, commands.length);
4646
+ lengthIndex = 0;
4647
+ for (const command of commands) {
4648
+ offset = writeBinaryValue(out, offset, command[1], byteLengths[lengthIndex] ?? 0);
4649
+ lengthIndex += 1;
4650
+ out.writeUInt16BE((command.length - 3) / 2, offset);
4651
+ offset += 2;
4652
+ for (let argumentIndex = 3; argumentIndex < command.length; argumentIndex += 1) {
4653
+ offset = writeBinaryValue(out, offset, command[argumentIndex], byteLengths[lengthIndex] ?? 0);
4654
+ lengthIndex += 1;
4655
+ }
4656
+ }
4657
+ return out;
4658
+ }
4552
4659
  function compactSetPipelinePayload(commands, maxBodyBytes) {
4553
4660
  let total = 6;
4554
4661
  const minimum = total + commands.length * 8;
@@ -5130,10 +5237,19 @@ function decodeValueAt(data, offset, limits, budget, depth) {
5130
5237
  const count = data.readUInt32BE(offset);
5131
5238
  requireValueContainer(count, depth, limits, budget);
5132
5239
  offset += 4;
5133
- const values = [];
5240
+ const values = new Array(count);
5241
+ if (count === 3) {
5242
+ const first = decodeValueAt(data, offset, limits, budget, depth + 1);
5243
+ const second = decodeValueAt(data, first.offset, limits, budget, depth + 1);
5244
+ const third = decodeValueAt(data, second.offset, limits, budget, depth + 1);
5245
+ values[0] = first.value;
5246
+ values[1] = second.value;
5247
+ values[2] = third.value;
5248
+ return { value: values, offset: third.offset };
5249
+ }
5134
5250
  for (let index = 0; index < count; index += 1) {
5135
5251
  const read = decodeValueAt(data, offset, limits, budget, depth + 1);
5136
- values.push(read.value);
5252
+ values[index] = read.value;
5137
5253
  offset = read.offset;
5138
5254
  }
5139
5255
  return { value: values, offset };
@@ -5450,6 +5566,8 @@ function nativeNegotiation(value) {
5450
5566
  compactResponseOpcodes: parseCompactResponseOpcodes(
5451
5567
  field(responseCodecs, "compact_response_opcodes")
5452
5568
  ),
5569
+ compactPubSubPublish: strictUnsigned16(field(field(field(capabilities, "pipeline"), "modes"), "pubsub_publish")) === 35,
5570
+ compactStreamXAdd: strictUnsigned16(field(field(field(capabilities, "pipeline"), "modes"), "stream_xadd_auto")) === 34,
5453
5571
  flowQuery: parseFlowQueryNegotiation(capabilities, schemas),
5454
5572
  ...maxResponseBytes == null ? {} : { maxResponseBytes }
5455
5573
  };
@@ -6742,8 +6860,13 @@ function buildProtocolCommand(args, maxBodyBytes = Number.MAX_SAFE_INTEGER, allo
6742
6860
  }
6743
6861
  return commandExec(args);
6744
6862
  }
6745
- function tryPipelineCommand(commands, maxBodyBytes = Number.MAX_SAFE_INTEGER) {
6746
- const compact = compactPipelinePayload(commands, maxBodyBytes);
6863
+ function tryPipelineCommand(commands, maxBodyBytes = Number.MAX_SAFE_INTEGER, allowStreamXAdd = true, allowPubSubPublish = true) {
6864
+ const compact = compactPipelinePayload(
6865
+ commands,
6866
+ maxBodyBytes,
6867
+ allowStreamXAdd,
6868
+ allowPubSubPublish
6869
+ );
6747
6870
  if (compact != null) {
6748
6871
  return {
6749
6872
  compactResponseItems: commands.length,
@@ -7244,13 +7367,18 @@ function surfaceIndividualCommandErrors(results, rejected, hasRejected, options)
7244
7367
  }
7245
7368
 
7246
7369
  // src/native-pipeline-execution.ts
7247
- async function executeNativeFusedPipeline(host, commands, laneId, options, maxPipelineCommands, maxRequestFrameBytes) {
7370
+ async function executeNativeFusedPipeline(host, commands, laneId, options, maxPipelineCommands, maxRequestFrameBytes, compactStreamXAdd = true, compactPubSubPublish = true) {
7248
7371
  commands = snapshotPipelineCommands(commands);
7249
7372
  options = snapshotPipelineOptions(options) ?? options;
7250
7373
  if (commands.length === 0) return [];
7251
7374
  if (maxPipelineCommands === 0 || commands.length > maxPipelineCommands) return void 0;
7252
7375
  try {
7253
- const pipeline = tryPipelineCommand(commands, maxRequestFrameBytes);
7376
+ const pipeline = tryPipelineCommand(
7377
+ commands,
7378
+ maxRequestFrameBytes,
7379
+ compactStreamXAdd,
7380
+ compactPubSubPublish
7381
+ );
7254
7382
  if (pipeline == null) return void 0;
7255
7383
  const response = await host.executeProtocolCommand(pipeline, laneId);
7256
7384
  return unwrapPipelineResponse(response, options, commands.length);
@@ -7259,7 +7387,7 @@ async function executeNativeFusedPipeline(host, commands, laneId, options, maxPi
7259
7387
  throw error;
7260
7388
  }
7261
7389
  }
7262
- async function executeNativePipeline(host, commands, laneId, options, maxPipelineCommands, maxRequestFrameBytes) {
7390
+ async function executeNativePipeline(host, commands, laneId, options, maxPipelineCommands, maxRequestFrameBytes, compactStreamXAdd = true, compactPubSubPublish = true) {
7263
7391
  commands = snapshotPipelineCommands(commands);
7264
7392
  options = snapshotPipelineOptions(options) ?? options;
7265
7393
  if (commands.length === 0) return [];
@@ -7267,7 +7395,15 @@ async function executeNativePipeline(host, commands, laneId, options, maxPipelin
7267
7395
  return await executeIndividually(host, commands, laneId, pipelineFallbackOptions(commands, options));
7268
7396
  }
7269
7397
  if (commands.length <= maxPipelineCommands) {
7270
- return await executeChunk(host, commands, laneId, options, maxRequestFrameBytes);
7398
+ return await executeChunk(
7399
+ host,
7400
+ commands,
7401
+ laneId,
7402
+ options,
7403
+ maxRequestFrameBytes,
7404
+ compactStreamXAdd,
7405
+ compactPubSubPublish
7406
+ );
7271
7407
  }
7272
7408
  const collectingOptions = pipelineErrorCollectingOptions(options);
7273
7409
  const results = new Array(commands.length);
@@ -7279,7 +7415,9 @@ async function executeNativePipeline(host, commands, laneId, options, maxPipelin
7279
7415
  chunk,
7280
7416
  laneId,
7281
7417
  pipelineSliceOptions(collectingOptions, start, start + chunk.length),
7282
- maxRequestFrameBytes
7418
+ maxRequestFrameBytes,
7419
+ compactStreamXAdd,
7420
+ compactPubSubPublish
7283
7421
  );
7284
7422
  for (let index = 0; index < chunkResults.length; index += 1) results[start + index] = chunkResults[index];
7285
7423
  rejected = collectPipelineRejections(chunkResults, start, rejected);
@@ -7287,9 +7425,14 @@ async function executeNativePipeline(host, commands, laneId, options, maxPipelin
7287
7425
  if (rejected != null) attachPipelineItemRejectionFlags(results, rejected);
7288
7426
  return surfaceFirstPipelineItemError(results, options);
7289
7427
  }
7290
- async function executeChunk(host, commands, laneId, options, maxRequestFrameBytes) {
7428
+ async function executeChunk(host, commands, laneId, options, maxRequestFrameBytes, compactStreamXAdd, compactPubSubPublish) {
7291
7429
  try {
7292
- const pipeline = tryPipelineCommand(commands, maxRequestFrameBytes);
7430
+ const pipeline = tryPipelineCommand(
7431
+ commands,
7432
+ maxRequestFrameBytes,
7433
+ compactStreamXAdd,
7434
+ compactPubSubPublish
7435
+ );
7293
7436
  if (pipeline != null) {
7294
7437
  const response = await host.executeProtocolCommand(pipeline, laneId);
7295
7438
  return unwrapPipelineResponse(response, options, commands.length);
@@ -7307,14 +7450,18 @@ async function executeChunk(host, commands, laneId, options, maxRequestFrameByte
7307
7450
  commands.slice(0, middle),
7308
7451
  laneId,
7309
7452
  pipelineSliceOptions(collectingOptions, 0, middle),
7310
- maxRequestFrameBytes
7453
+ maxRequestFrameBytes,
7454
+ compactStreamXAdd,
7455
+ compactPubSubPublish
7311
7456
  );
7312
7457
  const second = await executeChunk(
7313
7458
  host,
7314
7459
  commands.slice(middle),
7315
7460
  laneId,
7316
7461
  pipelineSliceOptions(collectingOptions, middle, commands.length),
7317
- maxRequestFrameBytes
7462
+ maxRequestFrameBytes,
7463
+ compactStreamXAdd,
7464
+ compactPubSubPublish
7318
7465
  );
7319
7466
  return surfaceFirstPipelineItemError(mergePipelineResults(first, second), options);
7320
7467
  }
@@ -7948,6 +8095,8 @@ var NativeConnectionCapabilities = class {
7948
8095
  }
7949
8096
  configuredRequestFrameBytes;
7950
8097
  compactResponseOpcodes = EMPTY_COMPACT_RESPONSE_OPCODES;
8098
+ compactPubSubPublish = false;
8099
+ compactStreamXAdd = false;
7951
8100
  flowQuery;
7952
8101
  requestFrameBytes;
7953
8102
  negotiatedRequestFrameBytes;
@@ -7955,6 +8104,8 @@ var NativeConnectionCapabilities = class {
7955
8104
  const limits = startupLimits(value);
7956
8105
  const negotiation = nativeNegotiation(value);
7957
8106
  this.compactResponseOpcodes = negotiation.compactResponseOpcodes;
8107
+ this.compactPubSubPublish = negotiation.compactPubSubPublish;
8108
+ this.compactStreamXAdd = negotiation.compactStreamXAdd;
7958
8109
  this.flowQuery = negotiation.flowQuery;
7959
8110
  if (limits.frameBytes != null) {
7960
8111
  this.negotiatedRequestFrameBytes = Math.min(
@@ -8180,7 +8331,9 @@ var NativeAdapter = class _NativeAdapter {
8180
8331
  laneId,
8181
8332
  options,
8182
8333
  this.maxPipelineCommands,
8183
- this.capabilities.requestFrameBytes
8334
+ this.capabilities.requestFrameBytes,
8335
+ this.capabilities.compactStreamXAdd,
8336
+ this.capabilities.compactPubSubPublish
8184
8337
  );
8185
8338
  }
8186
8339
  /** @internal Execute an ordered pipeline on a topology-selected lane. */
@@ -8191,7 +8344,9 @@ var NativeAdapter = class _NativeAdapter {
8191
8344
  laneId,
8192
8345
  options,
8193
8346
  this.maxPipelineCommands,
8194
- this.capabilities.requestFrameBytes
8347
+ this.capabilities.requestFrameBytes,
8348
+ this.capabilities.compactStreamXAdd,
8349
+ this.capabilities.compactPubSubPublish
8195
8350
  );
8196
8351
  }
8197
8352
  async close() {
@@ -20274,7 +20429,7 @@ var WorkflowWorker = class {
20274
20429
  };
20275
20430
 
20276
20431
  // src/version.ts
20277
- var FERRICSTORE_SDK_VERSION = "0.11.4";
20432
+ var FERRICSTORE_SDK_VERSION = "0.11.6";
20278
20433
  var FERRICSTORE_MINIMUM_SERVER_VERSION = "0.11.4";
20279
20434
  var FERRICSTORE_NATIVE_PROTOCOL_VERSION = 1;
20280
20435
  export {