@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.d.cts
CHANGED
|
@@ -145,6 +145,11 @@ declare const FEATURE_FLAGS: readonly [{
|
|
|
145
145
|
readonly description: string;
|
|
146
146
|
readonly default: false;
|
|
147
147
|
readonly env: "THREADBASE_FEATURE_LIVE_ACTIVITY_PUSH";
|
|
148
|
+
}, {
|
|
149
|
+
readonly id: "e2ee";
|
|
150
|
+
readonly description: string;
|
|
151
|
+
readonly default: false;
|
|
152
|
+
readonly env: "THREADBASE_FEATURE_E2EE";
|
|
148
153
|
}, {
|
|
149
154
|
readonly id: "ptyHost";
|
|
150
155
|
readonly description: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -145,6 +145,11 @@ declare const FEATURE_FLAGS: readonly [{
|
|
|
145
145
|
readonly description: string;
|
|
146
146
|
readonly default: false;
|
|
147
147
|
readonly env: "THREADBASE_FEATURE_LIVE_ACTIVITY_PUSH";
|
|
148
|
+
}, {
|
|
149
|
+
readonly id: "e2ee";
|
|
150
|
+
readonly description: string;
|
|
151
|
+
readonly default: false;
|
|
152
|
+
readonly env: "THREADBASE_FEATURE_E2EE";
|
|
148
153
|
}, {
|
|
149
154
|
readonly id: "ptyHost";
|
|
150
155
|
readonly description: string;
|
package/dist/index.js
CHANGED
|
@@ -464,6 +464,12 @@ var FEATURE_FLAGS = [
|
|
|
464
464
|
default: false,
|
|
465
465
|
env: "THREADBASE_FEATURE_LIVE_ACTIVITY_PUSH"
|
|
466
466
|
},
|
|
467
|
+
{
|
|
468
|
+
id: "e2ee",
|
|
469
|
+
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.",
|
|
470
|
+
default: false,
|
|
471
|
+
env: "THREADBASE_FEATURE_E2EE"
|
|
472
|
+
},
|
|
467
473
|
{
|
|
468
474
|
id: "ptyHost",
|
|
469
475
|
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.",
|
|
@@ -5734,6 +5740,25 @@ function describePushCapability(liveActivityEnabled, env = process.env) {
|
|
|
5734
5740
|
liveActivityReason: describeMissingApnsCredentials(env) ?? "APNs credentials are set but the push token store is unavailable, so Live Activity push is disabled."
|
|
5735
5741
|
};
|
|
5736
5742
|
}
|
|
5743
|
+
var E2EE_PROTOCOL_VERSION = 1;
|
|
5744
|
+
var E2EE_SUPPORTED = false;
|
|
5745
|
+
function describeE2eeCapability(flagEnabled) {
|
|
5746
|
+
const enabled = E2EE_SUPPORTED && flagEnabled;
|
|
5747
|
+
const base = {
|
|
5748
|
+
supported: E2EE_SUPPORTED,
|
|
5749
|
+
enabled,
|
|
5750
|
+
version: E2EE_PROTOCOL_VERSION,
|
|
5751
|
+
required: false
|
|
5752
|
+
};
|
|
5753
|
+
if (enabled) return base;
|
|
5754
|
+
return {
|
|
5755
|
+
...base,
|
|
5756
|
+
// Always says why, including when `supported` is false. An operator who set
|
|
5757
|
+
// the flag and saw nothing happen has exactly one question, and a field that
|
|
5758
|
+
// goes absent in the case they hit is the field not answering it.
|
|
5759
|
+
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"
|
|
5760
|
+
};
|
|
5761
|
+
}
|
|
5737
5762
|
var identityKeyFailureLogged = false;
|
|
5738
5763
|
function describeServerIdentityKey() {
|
|
5739
5764
|
try {
|
|
@@ -5788,7 +5813,11 @@ var createMiscRoutes = (deps) => {
|
|
|
5788
5813
|
// learn it without re-scanning. Additive: absent means a server with no
|
|
5789
5814
|
// readable identity key, which a client must read as "cannot verify this
|
|
5790
5815
|
// server" — never as a reason to fail the rest of this response.
|
|
5791
|
-
serverIdentityKey: describeServerIdentityKey()
|
|
5816
|
+
serverIdentityKey: describeServerIdentityKey(),
|
|
5817
|
+
// Whether to encrypt to this server. Additive, same contract as `push`:
|
|
5818
|
+
// absent means an older server, which a client must read as "unknown" and
|
|
5819
|
+
// resolve as today's plaintext path — never as a reason to fail.
|
|
5820
|
+
e2ee: describeE2eeCapability(deps.featureFlagsConfig().values.e2ee)
|
|
5792
5821
|
});
|
|
5793
5822
|
});
|
|
5794
5823
|
app.get("/api/profiles", (c) => c.json([]));
|
|
@@ -8242,6 +8271,7 @@ function readBody2(req) {
|
|
|
8242
8271
|
// src/api/handlers/conversations.handlers.ts
|
|
8243
8272
|
var SEARCH_OVERFETCH = 4;
|
|
8244
8273
|
var SEARCH_MAX_SCAN = 1e3;
|
|
8274
|
+
var MAX_BYTES_CEILING = 32 * 1024 * 1024;
|
|
8245
8275
|
var ConversationHandlers = class {
|
|
8246
8276
|
constructor(deps) {
|
|
8247
8277
|
this.deps = deps;
|
|
@@ -8647,7 +8677,7 @@ var ConversationHandlers = class {
|
|
|
8647
8677
|
const total = filtered.length;
|
|
8648
8678
|
const hasAnchor = url.searchParams.has("anchor_index");
|
|
8649
8679
|
const hasAfter = url.searchParams.has("after_index");
|
|
8650
|
-
const usePaging = url.searchParams.has("msg_limit") || url.searchParams.has("before_index") || hasAnchor || hasAfter;
|
|
8680
|
+
const usePaging = url.searchParams.has("msg_limit") || url.searchParams.has("before_index") || url.searchParams.has("max_bytes") || hasAnchor || hasAfter;
|
|
8651
8681
|
let slice = filtered;
|
|
8652
8682
|
let fromIdx = 0;
|
|
8653
8683
|
let messagePagination;
|
|
@@ -8769,6 +8799,28 @@ var ConversationHandlers = class {
|
|
|
8769
8799
|
content
|
|
8770
8800
|
};
|
|
8771
8801
|
});
|
|
8802
|
+
const requestedMaxBytes = intParam(url, "max_bytes", 0);
|
|
8803
|
+
if (requestedMaxBytes > 0 && messagesPayload.length > 0) {
|
|
8804
|
+
const budget = Math.min(requestedMaxBytes, MAX_BYTES_CEILING);
|
|
8805
|
+
let used = 0;
|
|
8806
|
+
let firstKept = messagesPayload.length - 1;
|
|
8807
|
+
for (let i = messagesPayload.length - 1; i >= 0; i--) {
|
|
8808
|
+
const size = Buffer.byteLength(JSON.stringify(messagesPayload[i]));
|
|
8809
|
+
if (i < messagesPayload.length - 1 && used + size > budget) break;
|
|
8810
|
+
used += size;
|
|
8811
|
+
firstKept = i;
|
|
8812
|
+
}
|
|
8813
|
+
if (firstKept > 0) {
|
|
8814
|
+
messagesPayload.splice(0, firstKept);
|
|
8815
|
+
if (messagePagination) {
|
|
8816
|
+
const newFrom = fromIdx + firstKept;
|
|
8817
|
+
messagePagination.from_index = newFrom;
|
|
8818
|
+
messagePagination.has_more_older = newFrom > 0;
|
|
8819
|
+
messagePagination.next_before_index = newFrom > 0 ? newFrom : null;
|
|
8820
|
+
}
|
|
8821
|
+
}
|
|
8822
|
+
if (messagePagination) messagePagination.served_bytes = used;
|
|
8823
|
+
}
|
|
8772
8824
|
const conv = conversation;
|
|
8773
8825
|
const cachedConvMeta = this.cache?.getMetaById(id);
|
|
8774
8826
|
const convProvider = coerceProviderForRunner(conv.provider ?? cachedConvMeta?.provider);
|