@threadbase-sh/streamer 1.55.4 → 1.57.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.cjs +54 -2
- package/dist/cli.cjs.map +1 -1
- package/dist/index.cjs +54 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +54 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -516,6 +516,12 @@ var FEATURE_FLAGS = [
|
|
|
516
516
|
default: false,
|
|
517
517
|
env: "THREADBASE_FEATURE_LIVE_ACTIVITY_PUSH"
|
|
518
518
|
},
|
|
519
|
+
{
|
|
520
|
+
id: "e2ee",
|
|
521
|
+
description: "Application-layer encryption between a paired device and this server, independent of TLS, so a tunnel or a LAN observer on the path carries ciphertext. Off by default: it is negotiated per device, never forced, because released mobile builds cannot be force-updated and a server that demanded it would break every one of them.",
|
|
522
|
+
default: false,
|
|
523
|
+
env: "THREADBASE_FEATURE_E2EE"
|
|
524
|
+
},
|
|
519
525
|
{
|
|
520
526
|
id: "ptyHost",
|
|
521
527
|
description: "Keep live PTYs in a separate host process so a streamer restart can reconnect without restarting the agents. Off by default until cross-platform behavior is qualified.",
|
|
@@ -5787,6 +5793,25 @@ function describePushCapability(liveActivityEnabled, env = process.env) {
|
|
|
5787
5793
|
liveActivityReason: describeMissingApnsCredentials(env) ?? "APNs credentials are set but the push token store is unavailable, so Live Activity push is disabled."
|
|
5788
5794
|
};
|
|
5789
5795
|
}
|
|
5796
|
+
var E2EE_PROTOCOL_VERSION = 1;
|
|
5797
|
+
var E2EE_SUPPORTED = false;
|
|
5798
|
+
function describeE2eeCapability(flagEnabled) {
|
|
5799
|
+
const enabled = E2EE_SUPPORTED && flagEnabled;
|
|
5800
|
+
const base = {
|
|
5801
|
+
supported: E2EE_SUPPORTED,
|
|
5802
|
+
enabled,
|
|
5803
|
+
version: E2EE_PROTOCOL_VERSION,
|
|
5804
|
+
required: false
|
|
5805
|
+
};
|
|
5806
|
+
if (enabled) return base;
|
|
5807
|
+
return {
|
|
5808
|
+
...base,
|
|
5809
|
+
// Always says why, including when `supported` is false. An operator who set
|
|
5810
|
+
// the flag and saw nothing happen has exactly one question, and a field that
|
|
5811
|
+
// goes absent in the case they hit is the field not answering it.
|
|
5812
|
+
reason: E2EE_SUPPORTED ? "disabled by the e2ee feature flag \u2014 set THREADBASE_FEATURE_E2EE=1, --feature e2ee=true, or feature_flags: in server.yaml" : "this build carries the capability negotiation but not yet the handshake it gates"
|
|
5813
|
+
};
|
|
5814
|
+
}
|
|
5790
5815
|
var identityKeyFailureLogged = false;
|
|
5791
5816
|
function describeServerIdentityKey() {
|
|
5792
5817
|
try {
|
|
@@ -5841,7 +5866,11 @@ var createMiscRoutes = (deps) => {
|
|
|
5841
5866
|
// learn it without re-scanning. Additive: absent means a server with no
|
|
5842
5867
|
// readable identity key, which a client must read as "cannot verify this
|
|
5843
5868
|
// server" — never as a reason to fail the rest of this response.
|
|
5844
|
-
serverIdentityKey: describeServerIdentityKey()
|
|
5869
|
+
serverIdentityKey: describeServerIdentityKey(),
|
|
5870
|
+
// Whether to encrypt to this server. Additive, same contract as `push`:
|
|
5871
|
+
// absent means an older server, which a client must read as "unknown" and
|
|
5872
|
+
// resolve as today's plaintext path — never as a reason to fail.
|
|
5873
|
+
e2ee: describeE2eeCapability(deps.featureFlagsConfig().values.e2ee)
|
|
5845
5874
|
});
|
|
5846
5875
|
});
|
|
5847
5876
|
app.get("/api/profiles", (c) => c.json([]));
|
|
@@ -8287,6 +8316,7 @@ function readBody2(req) {
|
|
|
8287
8316
|
// src/api/handlers/conversations.handlers.ts
|
|
8288
8317
|
var SEARCH_OVERFETCH = 4;
|
|
8289
8318
|
var SEARCH_MAX_SCAN = 1e3;
|
|
8319
|
+
var MAX_BYTES_CEILING = 32 * 1024 * 1024;
|
|
8290
8320
|
var ConversationHandlers = class {
|
|
8291
8321
|
constructor(deps) {
|
|
8292
8322
|
this.deps = deps;
|
|
@@ -8692,7 +8722,7 @@ var ConversationHandlers = class {
|
|
|
8692
8722
|
const total = filtered.length;
|
|
8693
8723
|
const hasAnchor = url.searchParams.has("anchor_index");
|
|
8694
8724
|
const hasAfter = url.searchParams.has("after_index");
|
|
8695
|
-
const usePaging = url.searchParams.has("msg_limit") || url.searchParams.has("before_index") || hasAnchor || hasAfter;
|
|
8725
|
+
const usePaging = url.searchParams.has("msg_limit") || url.searchParams.has("before_index") || url.searchParams.has("max_bytes") || hasAnchor || hasAfter;
|
|
8696
8726
|
let slice = filtered;
|
|
8697
8727
|
let fromIdx = 0;
|
|
8698
8728
|
let messagePagination;
|
|
@@ -8814,6 +8844,28 @@ var ConversationHandlers = class {
|
|
|
8814
8844
|
content
|
|
8815
8845
|
};
|
|
8816
8846
|
});
|
|
8847
|
+
const requestedMaxBytes = intParam(url, "max_bytes", 0);
|
|
8848
|
+
if (requestedMaxBytes > 0 && messagesPayload.length > 0) {
|
|
8849
|
+
const budget = Math.min(requestedMaxBytes, MAX_BYTES_CEILING);
|
|
8850
|
+
let used = 0;
|
|
8851
|
+
let firstKept = messagesPayload.length - 1;
|
|
8852
|
+
for (let i = messagesPayload.length - 1; i >= 0; i--) {
|
|
8853
|
+
const size = Buffer.byteLength(JSON.stringify(messagesPayload[i]));
|
|
8854
|
+
if (i < messagesPayload.length - 1 && used + size > budget) break;
|
|
8855
|
+
used += size;
|
|
8856
|
+
firstKept = i;
|
|
8857
|
+
}
|
|
8858
|
+
if (firstKept > 0) {
|
|
8859
|
+
messagesPayload.splice(0, firstKept);
|
|
8860
|
+
if (messagePagination) {
|
|
8861
|
+
const newFrom = fromIdx + firstKept;
|
|
8862
|
+
messagePagination.from_index = newFrom;
|
|
8863
|
+
messagePagination.has_more_older = newFrom > 0;
|
|
8864
|
+
messagePagination.next_before_index = newFrom > 0 ? newFrom : null;
|
|
8865
|
+
}
|
|
8866
|
+
}
|
|
8867
|
+
if (messagePagination) messagePagination.served_bytes = used;
|
|
8868
|
+
}
|
|
8817
8869
|
const conv = conversation;
|
|
8818
8870
|
const cachedConvMeta = this.cache?.getMetaById(id);
|
|
8819
8871
|
const convProvider = coerceProviderForRunner(conv.provider ?? cachedConvMeta?.provider);
|