@semilayer/core 0.1.0 → 0.1.2

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
@@ -4,7 +4,7 @@ type FacetName = (typeof FACET_NAMES)[number];
4
4
  declare const FUTURE_FACETS: readonly ["dedup", "classify"];
5
5
  declare const FIELD_TYPES: readonly ["text", "number", "boolean", "date", "json", "enum", "relation"];
6
6
  type FieldType = (typeof FIELD_TYPES)[number];
7
- declare const INGEST_JOB_TYPES: readonly ["full", "incremental", "delete", "records"];
7
+ declare const INGEST_JOB_TYPES: readonly ["full", "incremental", "delete", "records", "sync"];
8
8
  type IngestJobType = (typeof INGEST_JOB_TYPES)[number];
9
9
  declare const LENS_STATUSES: readonly ["paused", "indexing", "ready", "error"];
10
10
  type LensStatus = (typeof LENS_STATUSES)[number];
@@ -106,8 +106,31 @@ interface AuthConfig {
106
106
  rules?: LensRules;
107
107
  };
108
108
  }
109
+ /** Keys whose values are AccessRule. `stream` lives on LensRules but has its own shape. */
109
110
  type LensRuleKey = FacetName | 'query';
110
- type LensRules = Partial<Record<LensRuleKey, AccessRule>>;
111
+ /**
112
+ * Per-lens streaming configuration. Streaming is a transport, not a facet —
113
+ * it lives under `rules.stream` so it can be enabled, scoped to certain modes,
114
+ * or capped per-lens.
115
+ *
116
+ * - `enabled` defaults to `true` — streaming is on for any lens that has at
117
+ * least one supported facet.
118
+ * - `modes` defaults to both `['chunked', 'live']`. Restrict to disable a mode.
119
+ * - `maxLiveSubscriptions` is a per-lens cap on top of the org-wide tier limit.
120
+ *
121
+ * The canonical `StreamMode` type lives in `./stream.ts`.
122
+ */
123
+ interface StreamRules {
124
+ enabled?: boolean;
125
+ modes?: Array<'chunked' | 'live'>;
126
+ maxLiveSubscriptions?: number;
127
+ }
128
+ interface LensRules {
129
+ search?: AccessRule;
130
+ similar?: AccessRule;
131
+ query?: AccessRule;
132
+ stream?: StreamRules;
133
+ }
111
134
  interface EmbeddingConfig {
112
135
  provider: string;
113
136
  model: string;
@@ -298,12 +321,19 @@ interface IngestJobPayload {
298
321
  environmentId: string;
299
322
  lensName: string;
300
323
  sourceName: string;
301
- type: 'full' | 'incremental' | 'delete';
324
+ type: 'full' | 'incremental' | 'delete' | 'records' | 'sync';
302
325
  cursor?: string;
303
326
  /** True when triggered by a platform admin (bypasses quotas) */
304
327
  adminInvoked?: boolean;
305
328
  /** OIDC sub of the user who triggered this job */
306
329
  invokedBy?: string;
330
+ /**
331
+ * Smart sync only — when true, the sync handler wipes the partition first
332
+ * and then re-runs the full scan. Equivalent to the legacy "rebuild" flow.
333
+ * When false (default) the handler dedups against existing hashes and
334
+ * tombstones rows that disappeared from the source.
335
+ */
336
+ rebuild?: boolean;
307
337
  }
308
338
  /**
309
339
  * Full job data for v0.1 standalone/test mode.
@@ -356,7 +386,7 @@ interface LensStatusInfo {
356
386
  vectorCount: number;
357
387
  totalRows?: number;
358
388
  lastIngestAt?: Date;
359
- lastIngestType?: 'full' | 'incremental';
389
+ lastIngestType?: 'full' | 'incremental' | 'sync' | 'records';
360
390
  cursor?: string;
361
391
  error?: string;
362
392
  rateLimit?: RateLimitState;
@@ -434,6 +464,11 @@ interface Member {
434
464
  }
435
465
  interface IngestRun {
436
466
  id: string;
467
+ /**
468
+ * Which ingest path produced this run. Null for legacy rows from before
469
+ * the type column existed.
470
+ */
471
+ type: 'full' | 'incremental' | 'records' | 'sync' | null;
437
472
  status: IngestStatus;
438
473
  recordsProcessed: number;
439
474
  recordsFailed: number;
@@ -444,6 +479,17 @@ interface IngestRun {
444
479
  invokedBy: string | null;
445
480
  createdAt: ISODateString;
446
481
  }
482
+ /**
483
+ * Paginated response envelope used by list endpoints that grow with usage
484
+ * (ingest runs, jobs, etc.). `total` is the count after any filters are
485
+ * applied — use it to drive pagination UI without re-counting client-side.
486
+ */
487
+ interface Page<T> {
488
+ items: T[];
489
+ total: number;
490
+ limit: number;
491
+ offset: number;
492
+ }
447
493
  interface Tier {
448
494
  id: string;
449
495
  name: string;
@@ -465,6 +511,14 @@ interface Tier {
465
511
  orgsPerUser: number | null;
466
512
  /** Step 12 — per-minute ingest webhook rate limit. */
467
513
  ingestWebhooksPerMinute: number | null;
514
+ /** Streaming — concurrent WebSocket connections per org (per-pod enforced). */
515
+ concurrentWsConnections: number | null;
516
+ /** Streaming — sliding window of rows emitted via streaming per hour. */
517
+ wsRowsPerHour: number | null;
518
+ /** Streaming — concurrent live tail subscriptions per org. */
519
+ wsLiveSubscriptions: number | null;
520
+ /** Streaming — WS control-frame budget per minute (separate from apiRequestsPerMinute). */
521
+ wsOpsPerMinute: number | null;
468
522
  features: Record<string, unknown>;
469
523
  displayOrder: number;
470
524
  isDefault: boolean;
@@ -485,6 +539,11 @@ interface TierOverride {
485
539
  membersPerOrg: number | null;
486
540
  orgsPerUser: number | null;
487
541
  ingestWebhooksPerMinute: number | null;
542
+ /** Streaming — see Tier. Null = inherit from tier; explicit value overrides. */
543
+ concurrentWsConnections: number | null;
544
+ wsRowsPerHour: number | null;
545
+ wsLiveSubscriptions: number | null;
546
+ wsOpsPerMinute: number | null;
488
547
  features: Record<string, unknown> | null;
489
548
  note: string | null;
490
549
  createdAt: ISODateString;
@@ -926,6 +985,11 @@ interface TierFull {
926
985
  membersPerOrg: number | null;
927
986
  orgsPerUser: number | null;
928
987
  ingestWebhooksPerMinute: number | null;
988
+ /** Streaming — see Tier. */
989
+ concurrentWsConnections: number | null;
990
+ wsRowsPerHour: number | null;
991
+ wsLiveSubscriptions: number | null;
992
+ wsOpsPerMinute: number | null;
929
993
  features: Record<string, unknown>;
930
994
  displayOrder: number;
931
995
  isDefault: boolean;
@@ -1012,6 +1076,11 @@ interface TierOverrideRequest {
1012
1076
  membersPerOrg?: number | null;
1013
1077
  orgsPerUser?: number | null;
1014
1078
  ingestWebhooksPerMinute?: number | null;
1079
+ /** Streaming — see Tier. Null = inherit from tier. */
1080
+ concurrentWsConnections?: number | null;
1081
+ wsRowsPerHour?: number | null;
1082
+ wsLiveSubscriptions?: number | null;
1083
+ wsOpsPerMinute?: number | null;
1015
1084
  features?: Record<string, unknown> | null;
1016
1085
  note?: string | null;
1017
1086
  }
@@ -1024,9 +1093,165 @@ interface QuotaErrorResponse {
1024
1093
  upgradeUrl: string;
1025
1094
  }
1026
1095
 
1096
+ declare const STREAM_MODES: readonly ["chunked", "live"];
1097
+ type StreamMode = (typeof STREAM_MODES)[number];
1098
+ declare const LIVE_TAIL_MODES: readonly ["push", "polling", "unsupported"];
1099
+ type LiveTailMode = (typeof LIVE_TAIL_MODES)[number];
1100
+ /** WebSocket op names sent from client to server in the `op` field. */
1101
+ declare const STREAM_OPS: readonly ["search.stream", "query.stream", "subscribe", "observe", "unsubscribe"];
1102
+ type StreamOp = (typeof STREAM_OPS)[number];
1103
+ /** Frame `type` values for both directions. */
1104
+ declare const STREAM_FRAME_TYPES: readonly ["row", "done", "error", "event", "ping", "pong"];
1105
+ type StreamFrameType = (typeof STREAM_FRAME_TYPES)[number];
1106
+ /** Subscription event kinds (mirrors ingest write operations). */
1107
+ declare const STREAM_EVENT_KINDS: readonly ["insert", "update", "delete"];
1108
+ type StreamEventKind = (typeof STREAM_EVENT_KINDS)[number];
1109
+ /** Error codes carried in `error` frames. */
1110
+ declare const STREAM_ERROR_CODES: readonly ["rate_limited", "forbidden", "bad_request", "not_found", "internal"];
1111
+ type StreamErrorCode = (typeof STREAM_ERROR_CODES)[number];
1112
+ /**
1113
+ * WebSocket close codes.
1114
+ *
1115
+ * Reserved codes (1xxx) follow RFC 6455. The 4xxx range is application-defined.
1116
+ */
1117
+ declare const STREAM_CLOSE_CODES: {
1118
+ /** Normal close — client called .close() or server finished. */
1119
+ readonly normal: 1000;
1120
+ /** Server-side internal error. */
1121
+ readonly internal: 1011;
1122
+ /** Auth failed during the upgrade handshake. */
1123
+ readonly authFailed: 4401;
1124
+ /** Lens forbids streaming (rules.stream.enabled === false or modes[] excludes the requested mode). */
1125
+ readonly forbidden: 4403;
1126
+ /** Rate-limited at handshake — over `concurrentWsConnections` for the org. */
1127
+ readonly rateLimited: 4290;
1128
+ /** Mid-stream `wsRowsPerHour` quota exceeded. */
1129
+ readonly quotaExceeded: 4291;
1130
+ };
1131
+ type StreamCloseCode = (typeof STREAM_CLOSE_CODES)[keyof typeof STREAM_CLOSE_CODES];
1132
+ interface StreamSearchParams extends SearchParams {
1133
+ /** Optional batch size hint — server may ignore. Default: 50. */
1134
+ batchSize?: number;
1135
+ }
1136
+ interface StreamQueryParams extends QueryParams {
1137
+ /** Optional batch size hint — server may ignore. Default: 100. */
1138
+ batchSize?: number;
1139
+ }
1140
+ interface SubscribeParams {
1141
+ /**
1142
+ * Optional in-process filter applied to events before they're emitted.
1143
+ * v0.1: simple equality only. Complex predicate pushdown is a v0.2 feature.
1144
+ */
1145
+ filter?: Record<string, unknown>;
1146
+ }
1147
+ /**
1148
+ * One control frame sent from client to server. Multiple ops can ride a single
1149
+ * WebSocket connection — `id` is the multiplexing key the server echoes back
1150
+ * on response frames.
1151
+ */
1152
+ interface StreamOpFrame {
1153
+ id: string;
1154
+ op: StreamOp;
1155
+ params?: StreamSearchParams | StreamQueryParams | SubscribeParams | Record<string, unknown>;
1156
+ }
1157
+ interface StreamMeta {
1158
+ count: number;
1159
+ durationMs: number;
1160
+ }
1161
+ /** A row from a chunked search/query stream. */
1162
+ interface StreamRowFrame<T = Record<string, unknown>> {
1163
+ id: string;
1164
+ type: 'row';
1165
+ data: T;
1166
+ }
1167
+ /** Terminal frame for a chunked op — no more rows will arrive for this id. */
1168
+ interface StreamDoneFrame {
1169
+ id: string;
1170
+ type: 'done';
1171
+ meta: StreamMeta;
1172
+ }
1173
+ /** Subscription event — pushed for each matching ingest write. */
1174
+ interface StreamEventFrame<T = Record<string, unknown>> {
1175
+ id: string;
1176
+ type: 'event';
1177
+ kind: StreamEventKind;
1178
+ record: T;
1179
+ }
1180
+ /** Error attached to a specific op id (or global if id omitted). */
1181
+ interface StreamErrorFrame {
1182
+ id?: string;
1183
+ type: 'error';
1184
+ code: StreamErrorCode;
1185
+ message: string;
1186
+ }
1187
+ /** Server heartbeat. Client must reply with a `pong` frame. */
1188
+ interface StreamPingFrame {
1189
+ type: 'ping';
1190
+ }
1191
+ /** Client heartbeat reply. */
1192
+ interface StreamPongFrame {
1193
+ type: 'pong';
1194
+ }
1195
+ /** Discriminated union of every frame the server can send. */
1196
+ type StreamFrame<T = Record<string, unknown>> = StreamRowFrame<T> | StreamDoneFrame | StreamEventFrame<T> | StreamErrorFrame | StreamPingFrame | StreamPongFrame;
1197
+ /** What `BeamClient.subscribe()` yields per event. */
1198
+ interface StreamEvent<M = Record<string, unknown>> {
1199
+ kind: StreamEventKind;
1200
+ record: M;
1201
+ }
1202
+ /** What `BeamClient.streamSearch()` yields per row. */
1203
+ type StreamSearchRow<M = Record<string, unknown>> = SearchResult<M>;
1204
+ interface DeriveLiveTailModeInput {
1205
+ /** Lens rules — if `rules.stream.modes` excludes `'live'`, the mode is `unsupported`. */
1206
+ rules?: LensRules;
1207
+ /** Lens sync interval — presence implies polling-mode ingest. */
1208
+ syncInterval?: SyncInterval;
1209
+ /** Source feature flags from the bridge. */
1210
+ bridgeFeatures?: SourceFeature[];
1211
+ /**
1212
+ * Whether at least one ingest key (ik_) exists for the lens. This is a
1213
+ * runtime fact (DB-derived) — callers must look it up before invoking.
1214
+ */
1215
+ acceptsIngestKey: boolean;
1216
+ }
1217
+ /**
1218
+ * Is streaming enabled at all for this lens? Returns false only when the lens
1219
+ * config explicitly opts out via `rules.stream.enabled === false`. Default: true.
1220
+ *
1221
+ * This is the question the worker asks before populating the live tail buffer:
1222
+ * if a lens has streaming disabled, no one can subscribe, so there is no point
1223
+ * paying for the INSERT + NOTIFY.
1224
+ */
1225
+ declare function isStreamingEnabled(rules?: LensRules): boolean;
1226
+ /**
1227
+ * Is the `live` stream mode allowed for this lens? Returns false if streaming
1228
+ * is fully disabled OR if `rules.stream.modes` is set and excludes `'live'`.
1229
+ * Default: true.
1230
+ *
1231
+ * This is the gate for the worker's observation pathway. When false, the worker
1232
+ * skips the live tail buffer entirely — observation is microweight, but it is
1233
+ * not zero, and there is no value populating a buffer subscribers can never read.
1234
+ */
1235
+ declare function isLiveTailModeEnabled(rules?: LensRules): boolean;
1236
+ /**
1237
+ * Derive the live-tail mode for a lens.
1238
+ *
1239
+ * Live tail rides our **own ingest write path**, not bridge-native CDC. So as
1240
+ * long as records are being written to `vectors.embeddings` by *some* ingest
1241
+ * pathway, live tail works:
1242
+ *
1243
+ * - `'push'` — the lens accepts `ik_` ingest webhooks → near-realtime fan-out
1244
+ * - `'polling'` — the bridge supports incremental sync and a syncInterval is set
1245
+ * → smooth-but-bursty fan-out at the polling cadence
1246
+ * - `'unsupported'` — neither path is available, OR `rules.stream.modes`
1247
+ * explicitly excludes `'live'`. The Console Explorer disables the live tab
1248
+ * and the `subscribe` op returns a forbidden close code.
1249
+ */
1250
+ declare function deriveLiveTailMode(input: DeriveLiveTailModeInput): LiveTailMode;
1251
+
1027
1252
  declare function getDeploymentMode(): DeploymentMode;
1028
1253
  declare function isSaasMode(): boolean;
1029
1254
 
1030
1255
  declare function defineConfig(config: SemiLayerConfig): SemiLayerConfig;
1031
1256
 
1032
- export { type AccessRule, type AccessRuleResult, type AdminAssignUserBody, type AdminCashSnapshot, type AdminMrrSnapshot, type AdminOrgUsage, type AdminStripeEventRow, type AdminTopConsumerRow, type AdminTopConsumersResponse, type AdminUserDetail, type AdminUserListItem, type AdminUserListResponse, type AdminUserOrgMembership, type ApiKeyInfo, type AuditLogEntry, type AuthConfig, type AuthOrg, type AuthUser, type BannedIp, type BannedUser, type BannerData, type BillingCycleInfo, type BillingPlan, type BillingRedirectResponse, type BillingSnapshot, type Bridge, type BridgeConstructor, type BridgeRow, type BuiltinTransform, type CancelSubscriptionRequest, type CheckoutRequest, type ClaimCheck, type ClassifyFacetConfig, type ConfigExportResponse, type CreateEnvResponse, type CreateProjectResponse, DEPLOYMENT_MODES, type DailyMetrics, type DedupFacetConfig, type DeploymentMode, type DriftLensInfo, type DriftResponse, type EmbeddingConfig, type EmbeddingField, type Environment, type EnvironmentAuthConfig, type EnvsResponse, FACET_NAMES, FIELD_TYPES, FUTURE_FACETS, type FacetConfig, type FacetName, type FailedJobInfo, type FeedbackDetail, type FeedbackItem, type FieldConfig, type FieldType, INGEST_JOB_TYPES, INGEST_STATUSES, type ISODateString, type InAppNotification, type IngestControl, type IngestErrorEntry, type IngestJobData, type IngestJobPayload, type IngestJobType, type IngestRun, type IngestStatus, type InviteInfo, type Invoice, type JwtClaims, type JwtConfig, KEY_PREFIXES, LENS_STATUSES, type Lens, type LensComparison, type LensConfig, type LensCreateResponse, type LensRuleKey, type LensRules, type LensStatus, type LensStatusInfo, MERGE_STRATEGIES, type MeResponse, type Member, type MergeStrategy, type MetricPoint, type NewKeyPair, type NotificationPreferenceSummary, type OrderByClause, type Org, type OrgDetailResponse, type OrgListItem, type PendingInvite, type PendingInvitesResponse, type PlatformAdmin, type PlatformStats, type Project, type ProjectWithEnvs, type PushIngestJob, type PushLensSummary, type PushResponse, type QueryOptions, type QueryParams, type QueryResponse, type QueryResult, type QueueCounts, type QuotaErrorResponse, type RateLimitState, type ReadOptions, type ReadResult, SOURCE_FEATURES, type SearchFacetConfig, type SearchParams, type SearchResponse, type SearchResult, type SemiLayerConfig, type SimilarFacetConfig, type SimilarParams, type SimilarResponse, type Source, type SourceConfig, type SourceFeature, type StatusEnvironment, type StatusResponse, type SyncInterval, type SystemHealth, TRANSFORM_TYPES, type TargetColumnInfo, type TargetSchema, type Tier, type TierFull, type TierOverride, type TierOverrideRequest, type TierSummary, type TiersResponse, type TransformSpec, type TransformType, type TransportMode, type TransportOptions, type UsageMetricSnapshot, type WhereClause, canonicalHash, defineConfig, getDeploymentMode, isSaasMode, mapDbTypeToFieldType, resolveEmbeddingFieldNames, resolveEmbeddingFields, resolveSourceColumns, validateConfig };
1257
+ export { type AccessRule, type AccessRuleResult, type AdminAssignUserBody, type AdminCashSnapshot, type AdminMrrSnapshot, type AdminOrgUsage, type AdminStripeEventRow, type AdminTopConsumerRow, type AdminTopConsumersResponse, type AdminUserDetail, type AdminUserListItem, type AdminUserListResponse, type AdminUserOrgMembership, type ApiKeyInfo, type AuditLogEntry, type AuthConfig, type AuthOrg, type AuthUser, type BannedIp, type BannedUser, type BannerData, type BillingCycleInfo, type BillingPlan, type BillingRedirectResponse, type BillingSnapshot, type Bridge, type BridgeConstructor, type BridgeRow, type BuiltinTransform, type CancelSubscriptionRequest, type CheckoutRequest, type ClaimCheck, type ClassifyFacetConfig, type ConfigExportResponse, type CreateEnvResponse, type CreateProjectResponse, DEPLOYMENT_MODES, type DailyMetrics, type DedupFacetConfig, type DeploymentMode, type DeriveLiveTailModeInput, type DriftLensInfo, type DriftResponse, type EmbeddingConfig, type EmbeddingField, type Environment, type EnvironmentAuthConfig, type EnvsResponse, FACET_NAMES, FIELD_TYPES, FUTURE_FACETS, type FacetConfig, type FacetName, type FailedJobInfo, type FeedbackDetail, type FeedbackItem, type FieldConfig, type FieldType, INGEST_JOB_TYPES, INGEST_STATUSES, type ISODateString, type InAppNotification, type IngestControl, type IngestErrorEntry, type IngestJobData, type IngestJobPayload, type IngestJobType, type IngestRun, type IngestStatus, type InviteInfo, type Invoice, type JwtClaims, type JwtConfig, KEY_PREFIXES, LENS_STATUSES, LIVE_TAIL_MODES, type Lens, type LensComparison, type LensConfig, type LensCreateResponse, type LensRuleKey, type LensRules, type LensStatus, type LensStatusInfo, type LiveTailMode, MERGE_STRATEGIES, type MeResponse, type Member, type MergeStrategy, type MetricPoint, type NewKeyPair, type NotificationPreferenceSummary, type OrderByClause, type Org, type OrgDetailResponse, type OrgListItem, type Page, type PendingInvite, type PendingInvitesResponse, type PlatformAdmin, type PlatformStats, type Project, type ProjectWithEnvs, type PushIngestJob, type PushLensSummary, type PushResponse, type QueryOptions, type QueryParams, type QueryResponse, type QueryResult, type QueueCounts, type QuotaErrorResponse, type RateLimitState, type ReadOptions, type ReadResult, SOURCE_FEATURES, STREAM_CLOSE_CODES, STREAM_ERROR_CODES, STREAM_EVENT_KINDS, STREAM_FRAME_TYPES, STREAM_MODES, STREAM_OPS, type SearchFacetConfig, type SearchParams, type SearchResponse, type SearchResult, type SemiLayerConfig, type SimilarFacetConfig, type SimilarParams, type SimilarResponse, type Source, type SourceConfig, type SourceFeature, type StatusEnvironment, type StatusResponse, type StreamCloseCode, type StreamDoneFrame, type StreamErrorCode, type StreamErrorFrame, type StreamEvent, type StreamEventFrame, type StreamEventKind, type StreamFrame, type StreamFrameType, type StreamMeta, type StreamMode, type StreamOp, type StreamOpFrame, type StreamPingFrame, type StreamPongFrame, type StreamQueryParams, type StreamRowFrame, type StreamRules, type StreamSearchParams, type StreamSearchRow, type SubscribeParams, type SyncInterval, type SystemHealth, TRANSFORM_TYPES, type TargetColumnInfo, type TargetSchema, type Tier, type TierFull, type TierOverride, type TierOverrideRequest, type TierSummary, type TiersResponse, type TransformSpec, type TransformType, type TransportMode, type TransportOptions, type UsageMetricSnapshot, type WhereClause, canonicalHash, defineConfig, deriveLiveTailMode, getDeploymentMode, isLiveTailModeEnabled, isSaasMode, isStreamingEnabled, mapDbTypeToFieldType, resolveEmbeddingFieldNames, resolveEmbeddingFields, resolveSourceColumns, validateConfig };
package/dist/index.d.ts CHANGED
@@ -4,7 +4,7 @@ type FacetName = (typeof FACET_NAMES)[number];
4
4
  declare const FUTURE_FACETS: readonly ["dedup", "classify"];
5
5
  declare const FIELD_TYPES: readonly ["text", "number", "boolean", "date", "json", "enum", "relation"];
6
6
  type FieldType = (typeof FIELD_TYPES)[number];
7
- declare const INGEST_JOB_TYPES: readonly ["full", "incremental", "delete", "records"];
7
+ declare const INGEST_JOB_TYPES: readonly ["full", "incremental", "delete", "records", "sync"];
8
8
  type IngestJobType = (typeof INGEST_JOB_TYPES)[number];
9
9
  declare const LENS_STATUSES: readonly ["paused", "indexing", "ready", "error"];
10
10
  type LensStatus = (typeof LENS_STATUSES)[number];
@@ -106,8 +106,31 @@ interface AuthConfig {
106
106
  rules?: LensRules;
107
107
  };
108
108
  }
109
+ /** Keys whose values are AccessRule. `stream` lives on LensRules but has its own shape. */
109
110
  type LensRuleKey = FacetName | 'query';
110
- type LensRules = Partial<Record<LensRuleKey, AccessRule>>;
111
+ /**
112
+ * Per-lens streaming configuration. Streaming is a transport, not a facet —
113
+ * it lives under `rules.stream` so it can be enabled, scoped to certain modes,
114
+ * or capped per-lens.
115
+ *
116
+ * - `enabled` defaults to `true` — streaming is on for any lens that has at
117
+ * least one supported facet.
118
+ * - `modes` defaults to both `['chunked', 'live']`. Restrict to disable a mode.
119
+ * - `maxLiveSubscriptions` is a per-lens cap on top of the org-wide tier limit.
120
+ *
121
+ * The canonical `StreamMode` type lives in `./stream.ts`.
122
+ */
123
+ interface StreamRules {
124
+ enabled?: boolean;
125
+ modes?: Array<'chunked' | 'live'>;
126
+ maxLiveSubscriptions?: number;
127
+ }
128
+ interface LensRules {
129
+ search?: AccessRule;
130
+ similar?: AccessRule;
131
+ query?: AccessRule;
132
+ stream?: StreamRules;
133
+ }
111
134
  interface EmbeddingConfig {
112
135
  provider: string;
113
136
  model: string;
@@ -298,12 +321,19 @@ interface IngestJobPayload {
298
321
  environmentId: string;
299
322
  lensName: string;
300
323
  sourceName: string;
301
- type: 'full' | 'incremental' | 'delete';
324
+ type: 'full' | 'incremental' | 'delete' | 'records' | 'sync';
302
325
  cursor?: string;
303
326
  /** True when triggered by a platform admin (bypasses quotas) */
304
327
  adminInvoked?: boolean;
305
328
  /** OIDC sub of the user who triggered this job */
306
329
  invokedBy?: string;
330
+ /**
331
+ * Smart sync only — when true, the sync handler wipes the partition first
332
+ * and then re-runs the full scan. Equivalent to the legacy "rebuild" flow.
333
+ * When false (default) the handler dedups against existing hashes and
334
+ * tombstones rows that disappeared from the source.
335
+ */
336
+ rebuild?: boolean;
307
337
  }
308
338
  /**
309
339
  * Full job data for v0.1 standalone/test mode.
@@ -356,7 +386,7 @@ interface LensStatusInfo {
356
386
  vectorCount: number;
357
387
  totalRows?: number;
358
388
  lastIngestAt?: Date;
359
- lastIngestType?: 'full' | 'incremental';
389
+ lastIngestType?: 'full' | 'incremental' | 'sync' | 'records';
360
390
  cursor?: string;
361
391
  error?: string;
362
392
  rateLimit?: RateLimitState;
@@ -434,6 +464,11 @@ interface Member {
434
464
  }
435
465
  interface IngestRun {
436
466
  id: string;
467
+ /**
468
+ * Which ingest path produced this run. Null for legacy rows from before
469
+ * the type column existed.
470
+ */
471
+ type: 'full' | 'incremental' | 'records' | 'sync' | null;
437
472
  status: IngestStatus;
438
473
  recordsProcessed: number;
439
474
  recordsFailed: number;
@@ -444,6 +479,17 @@ interface IngestRun {
444
479
  invokedBy: string | null;
445
480
  createdAt: ISODateString;
446
481
  }
482
+ /**
483
+ * Paginated response envelope used by list endpoints that grow with usage
484
+ * (ingest runs, jobs, etc.). `total` is the count after any filters are
485
+ * applied — use it to drive pagination UI without re-counting client-side.
486
+ */
487
+ interface Page<T> {
488
+ items: T[];
489
+ total: number;
490
+ limit: number;
491
+ offset: number;
492
+ }
447
493
  interface Tier {
448
494
  id: string;
449
495
  name: string;
@@ -465,6 +511,14 @@ interface Tier {
465
511
  orgsPerUser: number | null;
466
512
  /** Step 12 — per-minute ingest webhook rate limit. */
467
513
  ingestWebhooksPerMinute: number | null;
514
+ /** Streaming — concurrent WebSocket connections per org (per-pod enforced). */
515
+ concurrentWsConnections: number | null;
516
+ /** Streaming — sliding window of rows emitted via streaming per hour. */
517
+ wsRowsPerHour: number | null;
518
+ /** Streaming — concurrent live tail subscriptions per org. */
519
+ wsLiveSubscriptions: number | null;
520
+ /** Streaming — WS control-frame budget per minute (separate from apiRequestsPerMinute). */
521
+ wsOpsPerMinute: number | null;
468
522
  features: Record<string, unknown>;
469
523
  displayOrder: number;
470
524
  isDefault: boolean;
@@ -485,6 +539,11 @@ interface TierOverride {
485
539
  membersPerOrg: number | null;
486
540
  orgsPerUser: number | null;
487
541
  ingestWebhooksPerMinute: number | null;
542
+ /** Streaming — see Tier. Null = inherit from tier; explicit value overrides. */
543
+ concurrentWsConnections: number | null;
544
+ wsRowsPerHour: number | null;
545
+ wsLiveSubscriptions: number | null;
546
+ wsOpsPerMinute: number | null;
488
547
  features: Record<string, unknown> | null;
489
548
  note: string | null;
490
549
  createdAt: ISODateString;
@@ -926,6 +985,11 @@ interface TierFull {
926
985
  membersPerOrg: number | null;
927
986
  orgsPerUser: number | null;
928
987
  ingestWebhooksPerMinute: number | null;
988
+ /** Streaming — see Tier. */
989
+ concurrentWsConnections: number | null;
990
+ wsRowsPerHour: number | null;
991
+ wsLiveSubscriptions: number | null;
992
+ wsOpsPerMinute: number | null;
929
993
  features: Record<string, unknown>;
930
994
  displayOrder: number;
931
995
  isDefault: boolean;
@@ -1012,6 +1076,11 @@ interface TierOverrideRequest {
1012
1076
  membersPerOrg?: number | null;
1013
1077
  orgsPerUser?: number | null;
1014
1078
  ingestWebhooksPerMinute?: number | null;
1079
+ /** Streaming — see Tier. Null = inherit from tier. */
1080
+ concurrentWsConnections?: number | null;
1081
+ wsRowsPerHour?: number | null;
1082
+ wsLiveSubscriptions?: number | null;
1083
+ wsOpsPerMinute?: number | null;
1015
1084
  features?: Record<string, unknown> | null;
1016
1085
  note?: string | null;
1017
1086
  }
@@ -1024,9 +1093,165 @@ interface QuotaErrorResponse {
1024
1093
  upgradeUrl: string;
1025
1094
  }
1026
1095
 
1096
+ declare const STREAM_MODES: readonly ["chunked", "live"];
1097
+ type StreamMode = (typeof STREAM_MODES)[number];
1098
+ declare const LIVE_TAIL_MODES: readonly ["push", "polling", "unsupported"];
1099
+ type LiveTailMode = (typeof LIVE_TAIL_MODES)[number];
1100
+ /** WebSocket op names sent from client to server in the `op` field. */
1101
+ declare const STREAM_OPS: readonly ["search.stream", "query.stream", "subscribe", "observe", "unsubscribe"];
1102
+ type StreamOp = (typeof STREAM_OPS)[number];
1103
+ /** Frame `type` values for both directions. */
1104
+ declare const STREAM_FRAME_TYPES: readonly ["row", "done", "error", "event", "ping", "pong"];
1105
+ type StreamFrameType = (typeof STREAM_FRAME_TYPES)[number];
1106
+ /** Subscription event kinds (mirrors ingest write operations). */
1107
+ declare const STREAM_EVENT_KINDS: readonly ["insert", "update", "delete"];
1108
+ type StreamEventKind = (typeof STREAM_EVENT_KINDS)[number];
1109
+ /** Error codes carried in `error` frames. */
1110
+ declare const STREAM_ERROR_CODES: readonly ["rate_limited", "forbidden", "bad_request", "not_found", "internal"];
1111
+ type StreamErrorCode = (typeof STREAM_ERROR_CODES)[number];
1112
+ /**
1113
+ * WebSocket close codes.
1114
+ *
1115
+ * Reserved codes (1xxx) follow RFC 6455. The 4xxx range is application-defined.
1116
+ */
1117
+ declare const STREAM_CLOSE_CODES: {
1118
+ /** Normal close — client called .close() or server finished. */
1119
+ readonly normal: 1000;
1120
+ /** Server-side internal error. */
1121
+ readonly internal: 1011;
1122
+ /** Auth failed during the upgrade handshake. */
1123
+ readonly authFailed: 4401;
1124
+ /** Lens forbids streaming (rules.stream.enabled === false or modes[] excludes the requested mode). */
1125
+ readonly forbidden: 4403;
1126
+ /** Rate-limited at handshake — over `concurrentWsConnections` for the org. */
1127
+ readonly rateLimited: 4290;
1128
+ /** Mid-stream `wsRowsPerHour` quota exceeded. */
1129
+ readonly quotaExceeded: 4291;
1130
+ };
1131
+ type StreamCloseCode = (typeof STREAM_CLOSE_CODES)[keyof typeof STREAM_CLOSE_CODES];
1132
+ interface StreamSearchParams extends SearchParams {
1133
+ /** Optional batch size hint — server may ignore. Default: 50. */
1134
+ batchSize?: number;
1135
+ }
1136
+ interface StreamQueryParams extends QueryParams {
1137
+ /** Optional batch size hint — server may ignore. Default: 100. */
1138
+ batchSize?: number;
1139
+ }
1140
+ interface SubscribeParams {
1141
+ /**
1142
+ * Optional in-process filter applied to events before they're emitted.
1143
+ * v0.1: simple equality only. Complex predicate pushdown is a v0.2 feature.
1144
+ */
1145
+ filter?: Record<string, unknown>;
1146
+ }
1147
+ /**
1148
+ * One control frame sent from client to server. Multiple ops can ride a single
1149
+ * WebSocket connection — `id` is the multiplexing key the server echoes back
1150
+ * on response frames.
1151
+ */
1152
+ interface StreamOpFrame {
1153
+ id: string;
1154
+ op: StreamOp;
1155
+ params?: StreamSearchParams | StreamQueryParams | SubscribeParams | Record<string, unknown>;
1156
+ }
1157
+ interface StreamMeta {
1158
+ count: number;
1159
+ durationMs: number;
1160
+ }
1161
+ /** A row from a chunked search/query stream. */
1162
+ interface StreamRowFrame<T = Record<string, unknown>> {
1163
+ id: string;
1164
+ type: 'row';
1165
+ data: T;
1166
+ }
1167
+ /** Terminal frame for a chunked op — no more rows will arrive for this id. */
1168
+ interface StreamDoneFrame {
1169
+ id: string;
1170
+ type: 'done';
1171
+ meta: StreamMeta;
1172
+ }
1173
+ /** Subscription event — pushed for each matching ingest write. */
1174
+ interface StreamEventFrame<T = Record<string, unknown>> {
1175
+ id: string;
1176
+ type: 'event';
1177
+ kind: StreamEventKind;
1178
+ record: T;
1179
+ }
1180
+ /** Error attached to a specific op id (or global if id omitted). */
1181
+ interface StreamErrorFrame {
1182
+ id?: string;
1183
+ type: 'error';
1184
+ code: StreamErrorCode;
1185
+ message: string;
1186
+ }
1187
+ /** Server heartbeat. Client must reply with a `pong` frame. */
1188
+ interface StreamPingFrame {
1189
+ type: 'ping';
1190
+ }
1191
+ /** Client heartbeat reply. */
1192
+ interface StreamPongFrame {
1193
+ type: 'pong';
1194
+ }
1195
+ /** Discriminated union of every frame the server can send. */
1196
+ type StreamFrame<T = Record<string, unknown>> = StreamRowFrame<T> | StreamDoneFrame | StreamEventFrame<T> | StreamErrorFrame | StreamPingFrame | StreamPongFrame;
1197
+ /** What `BeamClient.subscribe()` yields per event. */
1198
+ interface StreamEvent<M = Record<string, unknown>> {
1199
+ kind: StreamEventKind;
1200
+ record: M;
1201
+ }
1202
+ /** What `BeamClient.streamSearch()` yields per row. */
1203
+ type StreamSearchRow<M = Record<string, unknown>> = SearchResult<M>;
1204
+ interface DeriveLiveTailModeInput {
1205
+ /** Lens rules — if `rules.stream.modes` excludes `'live'`, the mode is `unsupported`. */
1206
+ rules?: LensRules;
1207
+ /** Lens sync interval — presence implies polling-mode ingest. */
1208
+ syncInterval?: SyncInterval;
1209
+ /** Source feature flags from the bridge. */
1210
+ bridgeFeatures?: SourceFeature[];
1211
+ /**
1212
+ * Whether at least one ingest key (ik_) exists for the lens. This is a
1213
+ * runtime fact (DB-derived) — callers must look it up before invoking.
1214
+ */
1215
+ acceptsIngestKey: boolean;
1216
+ }
1217
+ /**
1218
+ * Is streaming enabled at all for this lens? Returns false only when the lens
1219
+ * config explicitly opts out via `rules.stream.enabled === false`. Default: true.
1220
+ *
1221
+ * This is the question the worker asks before populating the live tail buffer:
1222
+ * if a lens has streaming disabled, no one can subscribe, so there is no point
1223
+ * paying for the INSERT + NOTIFY.
1224
+ */
1225
+ declare function isStreamingEnabled(rules?: LensRules): boolean;
1226
+ /**
1227
+ * Is the `live` stream mode allowed for this lens? Returns false if streaming
1228
+ * is fully disabled OR if `rules.stream.modes` is set and excludes `'live'`.
1229
+ * Default: true.
1230
+ *
1231
+ * This is the gate for the worker's observation pathway. When false, the worker
1232
+ * skips the live tail buffer entirely — observation is microweight, but it is
1233
+ * not zero, and there is no value populating a buffer subscribers can never read.
1234
+ */
1235
+ declare function isLiveTailModeEnabled(rules?: LensRules): boolean;
1236
+ /**
1237
+ * Derive the live-tail mode for a lens.
1238
+ *
1239
+ * Live tail rides our **own ingest write path**, not bridge-native CDC. So as
1240
+ * long as records are being written to `vectors.embeddings` by *some* ingest
1241
+ * pathway, live tail works:
1242
+ *
1243
+ * - `'push'` — the lens accepts `ik_` ingest webhooks → near-realtime fan-out
1244
+ * - `'polling'` — the bridge supports incremental sync and a syncInterval is set
1245
+ * → smooth-but-bursty fan-out at the polling cadence
1246
+ * - `'unsupported'` — neither path is available, OR `rules.stream.modes`
1247
+ * explicitly excludes `'live'`. The Console Explorer disables the live tab
1248
+ * and the `subscribe` op returns a forbidden close code.
1249
+ */
1250
+ declare function deriveLiveTailMode(input: DeriveLiveTailModeInput): LiveTailMode;
1251
+
1027
1252
  declare function getDeploymentMode(): DeploymentMode;
1028
1253
  declare function isSaasMode(): boolean;
1029
1254
 
1030
1255
  declare function defineConfig(config: SemiLayerConfig): SemiLayerConfig;
1031
1256
 
1032
- export { type AccessRule, type AccessRuleResult, type AdminAssignUserBody, type AdminCashSnapshot, type AdminMrrSnapshot, type AdminOrgUsage, type AdminStripeEventRow, type AdminTopConsumerRow, type AdminTopConsumersResponse, type AdminUserDetail, type AdminUserListItem, type AdminUserListResponse, type AdminUserOrgMembership, type ApiKeyInfo, type AuditLogEntry, type AuthConfig, type AuthOrg, type AuthUser, type BannedIp, type BannedUser, type BannerData, type BillingCycleInfo, type BillingPlan, type BillingRedirectResponse, type BillingSnapshot, type Bridge, type BridgeConstructor, type BridgeRow, type BuiltinTransform, type CancelSubscriptionRequest, type CheckoutRequest, type ClaimCheck, type ClassifyFacetConfig, type ConfigExportResponse, type CreateEnvResponse, type CreateProjectResponse, DEPLOYMENT_MODES, type DailyMetrics, type DedupFacetConfig, type DeploymentMode, type DriftLensInfo, type DriftResponse, type EmbeddingConfig, type EmbeddingField, type Environment, type EnvironmentAuthConfig, type EnvsResponse, FACET_NAMES, FIELD_TYPES, FUTURE_FACETS, type FacetConfig, type FacetName, type FailedJobInfo, type FeedbackDetail, type FeedbackItem, type FieldConfig, type FieldType, INGEST_JOB_TYPES, INGEST_STATUSES, type ISODateString, type InAppNotification, type IngestControl, type IngestErrorEntry, type IngestJobData, type IngestJobPayload, type IngestJobType, type IngestRun, type IngestStatus, type InviteInfo, type Invoice, type JwtClaims, type JwtConfig, KEY_PREFIXES, LENS_STATUSES, type Lens, type LensComparison, type LensConfig, type LensCreateResponse, type LensRuleKey, type LensRules, type LensStatus, type LensStatusInfo, MERGE_STRATEGIES, type MeResponse, type Member, type MergeStrategy, type MetricPoint, type NewKeyPair, type NotificationPreferenceSummary, type OrderByClause, type Org, type OrgDetailResponse, type OrgListItem, type PendingInvite, type PendingInvitesResponse, type PlatformAdmin, type PlatformStats, type Project, type ProjectWithEnvs, type PushIngestJob, type PushLensSummary, type PushResponse, type QueryOptions, type QueryParams, type QueryResponse, type QueryResult, type QueueCounts, type QuotaErrorResponse, type RateLimitState, type ReadOptions, type ReadResult, SOURCE_FEATURES, type SearchFacetConfig, type SearchParams, type SearchResponse, type SearchResult, type SemiLayerConfig, type SimilarFacetConfig, type SimilarParams, type SimilarResponse, type Source, type SourceConfig, type SourceFeature, type StatusEnvironment, type StatusResponse, type SyncInterval, type SystemHealth, TRANSFORM_TYPES, type TargetColumnInfo, type TargetSchema, type Tier, type TierFull, type TierOverride, type TierOverrideRequest, type TierSummary, type TiersResponse, type TransformSpec, type TransformType, type TransportMode, type TransportOptions, type UsageMetricSnapshot, type WhereClause, canonicalHash, defineConfig, getDeploymentMode, isSaasMode, mapDbTypeToFieldType, resolveEmbeddingFieldNames, resolveEmbeddingFields, resolveSourceColumns, validateConfig };
1257
+ export { type AccessRule, type AccessRuleResult, type AdminAssignUserBody, type AdminCashSnapshot, type AdminMrrSnapshot, type AdminOrgUsage, type AdminStripeEventRow, type AdminTopConsumerRow, type AdminTopConsumersResponse, type AdminUserDetail, type AdminUserListItem, type AdminUserListResponse, type AdminUserOrgMembership, type ApiKeyInfo, type AuditLogEntry, type AuthConfig, type AuthOrg, type AuthUser, type BannedIp, type BannedUser, type BannerData, type BillingCycleInfo, type BillingPlan, type BillingRedirectResponse, type BillingSnapshot, type Bridge, type BridgeConstructor, type BridgeRow, type BuiltinTransform, type CancelSubscriptionRequest, type CheckoutRequest, type ClaimCheck, type ClassifyFacetConfig, type ConfigExportResponse, type CreateEnvResponse, type CreateProjectResponse, DEPLOYMENT_MODES, type DailyMetrics, type DedupFacetConfig, type DeploymentMode, type DeriveLiveTailModeInput, type DriftLensInfo, type DriftResponse, type EmbeddingConfig, type EmbeddingField, type Environment, type EnvironmentAuthConfig, type EnvsResponse, FACET_NAMES, FIELD_TYPES, FUTURE_FACETS, type FacetConfig, type FacetName, type FailedJobInfo, type FeedbackDetail, type FeedbackItem, type FieldConfig, type FieldType, INGEST_JOB_TYPES, INGEST_STATUSES, type ISODateString, type InAppNotification, type IngestControl, type IngestErrorEntry, type IngestJobData, type IngestJobPayload, type IngestJobType, type IngestRun, type IngestStatus, type InviteInfo, type Invoice, type JwtClaims, type JwtConfig, KEY_PREFIXES, LENS_STATUSES, LIVE_TAIL_MODES, type Lens, type LensComparison, type LensConfig, type LensCreateResponse, type LensRuleKey, type LensRules, type LensStatus, type LensStatusInfo, type LiveTailMode, MERGE_STRATEGIES, type MeResponse, type Member, type MergeStrategy, type MetricPoint, type NewKeyPair, type NotificationPreferenceSummary, type OrderByClause, type Org, type OrgDetailResponse, type OrgListItem, type Page, type PendingInvite, type PendingInvitesResponse, type PlatformAdmin, type PlatformStats, type Project, type ProjectWithEnvs, type PushIngestJob, type PushLensSummary, type PushResponse, type QueryOptions, type QueryParams, type QueryResponse, type QueryResult, type QueueCounts, type QuotaErrorResponse, type RateLimitState, type ReadOptions, type ReadResult, SOURCE_FEATURES, STREAM_CLOSE_CODES, STREAM_ERROR_CODES, STREAM_EVENT_KINDS, STREAM_FRAME_TYPES, STREAM_MODES, STREAM_OPS, type SearchFacetConfig, type SearchParams, type SearchResponse, type SearchResult, type SemiLayerConfig, type SimilarFacetConfig, type SimilarParams, type SimilarResponse, type Source, type SourceConfig, type SourceFeature, type StatusEnvironment, type StatusResponse, type StreamCloseCode, type StreamDoneFrame, type StreamErrorCode, type StreamErrorFrame, type StreamEvent, type StreamEventFrame, type StreamEventKind, type StreamFrame, type StreamFrameType, type StreamMeta, type StreamMode, type StreamOp, type StreamOpFrame, type StreamPingFrame, type StreamPongFrame, type StreamQueryParams, type StreamRowFrame, type StreamRules, type StreamSearchParams, type StreamSearchRow, type SubscribeParams, type SyncInterval, type SystemHealth, TRANSFORM_TYPES, type TargetColumnInfo, type TargetSchema, type Tier, type TierFull, type TierOverride, type TierOverrideRequest, type TierSummary, type TiersResponse, type TransformSpec, type TransformType, type TransportMode, type TransportOptions, type UsageMetricSnapshot, type WhereClause, canonicalHash, defineConfig, deriveLiveTailMode, getDeploymentMode, isLiveTailModeEnabled, isSaasMode, isStreamingEnabled, mapDbTypeToFieldType, resolveEmbeddingFieldNames, resolveEmbeddingFields, resolveSourceColumns, validateConfig };