@cloudbitmaps/roaring 0.9.0 → 0.10.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/NOTICE +3 -3
- package/PRIVACY.md +198 -72
- package/README.md +121 -57
- package/dist/bin/export-segments.d.ts +21 -0
- package/dist/bin/export-segments.js +1508 -30
- package/dist/bin/export-segments.js.map +7 -1
- package/dist/codec-bound.d.ts +38 -0
- package/dist/index.d.ts +805 -447
- package/dist/index.js +911 -325
- package/dist/index.js.map +7 -1
- package/dist/moved-options.d.ts +14 -0
- package/dist/portable/decode.d.ts +54 -0
- package/dist/roaring-codec.d.ts +61 -0
- package/dist/system-clock.d.ts +40 -0
- package/dist/testing/conformance.d.ts +34 -0
- package/dist/testing/fuzz-codec.d.ts +9 -0
- package/package.json +11 -116
- package/dist/azure/index.cjs +0 -14
- package/dist/azure/index.cjs.map +0 -1
- package/dist/azure/index.d.cts +0 -9
- package/dist/azure/index.d.ts +0 -9
- package/dist/azure/index.js +0 -3
- package/dist/azure/index.js.map +0 -1
- package/dist/bin/compact-segments.js +0 -201
- package/dist/bin/compact-segments.js.map +0 -1
- package/dist/cassandra/index.cjs +0 -14
- package/dist/cassandra/index.cjs.map +0 -1
- package/dist/cassandra/index.d.cts +0 -1
- package/dist/cassandra/index.d.ts +0 -1
- package/dist/cassandra/index.js +0 -3
- package/dist/cassandra/index.js.map +0 -1
- package/dist/chunk-D6LIJSGF.js +0 -906
- package/dist/chunk-D6LIJSGF.js.map +0 -1
- package/dist/dynamodb/index.cjs +0 -14
- package/dist/dynamodb/index.cjs.map +0 -1
- package/dist/dynamodb/index.d.cts +0 -1
- package/dist/dynamodb/index.d.ts +0 -1
- package/dist/dynamodb/index.js +0 -3
- package/dist/dynamodb/index.js.map +0 -1
- package/dist/gcs/index.cjs +0 -14
- package/dist/gcs/index.cjs.map +0 -1
- package/dist/gcs/index.d.cts +0 -1
- package/dist/gcs/index.d.ts +0 -1
- package/dist/gcs/index.js +0 -3
- package/dist/gcs/index.js.map +0 -1
- package/dist/index.cjs +0 -894
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.cts +0 -734
- package/dist/mongodb/index.cjs +0 -14
- package/dist/mongodb/index.cjs.map +0 -1
- package/dist/mongodb/index.d.cts +0 -1
- package/dist/mongodb/index.d.ts +0 -1
- package/dist/mongodb/index.js +0 -3
- package/dist/mongodb/index.js.map +0 -1
- package/dist/mysql/index.cjs +0 -14
- package/dist/mysql/index.cjs.map +0 -1
- package/dist/mysql/index.d.cts +0 -1
- package/dist/mysql/index.d.ts +0 -1
- package/dist/mysql/index.js +0 -3
- package/dist/mysql/index.js.map +0 -1
- package/dist/postgres/index.cjs +0 -14
- package/dist/postgres/index.cjs.map +0 -1
- package/dist/postgres/index.d.cts +0 -1
- package/dist/postgres/index.d.ts +0 -1
- package/dist/postgres/index.js +0 -3
- package/dist/postgres/index.js.map +0 -1
- package/dist/redis/index.cjs +0 -14
- package/dist/redis/index.cjs.map +0 -1
- package/dist/redis/index.d.cts +0 -1
- package/dist/redis/index.d.ts +0 -1
- package/dist/redis/index.js +0 -3
- package/dist/redis/index.js.map +0 -1
- package/dist/s3/index.cjs +0 -14
- package/dist/s3/index.cjs.map +0 -1
- package/dist/s3/index.d.cts +0 -1
- package/dist/s3/index.d.ts +0 -1
- package/dist/s3/index.js +0 -3
- package/dist/s3/index.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/bin/compact-segments.ts"],"names":[],"mappings":"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","file":"compact-segments.js","sourcesContent":["#!/usr/bin/env node\n/**\n * `compact-segments` — the standalone compaction daemon CLI (Phase 4d).\n *\n * A thin wrapper over {@link runCompactionCycle}: discover dirty segments → 2-phase-commit compact → GC. It\n * ships the **local-filesystem** backend (zero-dependency, the dev/reference target) and two **deploy modes**:\n *\n * - `once` — run a single cycle and exit (the **Lambda / one-shot / cron** shape).\n * - `loop` — run a cycle every `intervalMs`, until SIGINT/SIGTERM (the **K8s Deployment / ECS service** shape).\n *\n * **Cloud backends:** rather than have the CLI guess your AWS config, production wires its own ~10-line\n * handler that constructs an `S3ColdDriver` + `DynamoDb{Warm,Registry}Driver` and calls `runCompactionCycle`\n * directly (same two modes — call once, or on a `setInterval`). The library exports everything needed; this\n * binary stays SDK-free (so the core install never pulls a cloud SDK). See the getting-started guide.\n *\n * Config is read from the environment (so it's identical across `once`/`loop` and 12-factor-friendly):\n * CR_COMPACT_ROOT (required) — the local-filesystem root holding cold/ warm/ registry/\n * CR_COMPACT_MODE once | loop (default: once)\n * CR_COMPACT_INTERVAL_MS (default: 30000, loop mode)\n * CR_COMPACT_NAMESPACE scope discovery to one namespace\n * CR_COMPACT_THRESHOLD min dirty chunks to compact (default: 1)\n * CR_COMPACT_KEEP superseded generations to retain as a reader grace window (default: 1)\n * CR_COMPACT_OWNER lease owner id (default: `<hostname>:<pid>`)\n * CR_COMPACT_SHARD / CR_COMPACT_TOTAL_SHARDS run this worker as shard i of N (set both) — partition the\n * fleet across N daemons so each drains only ~1/N of Warm per cycle (gap #3)\n * CR_COMPACT_MAX_SEGMENTS cap segments compacted per cycle (a time budget for a Lambda window); the rest\n * are deferred to the next cycle, most-dirty first\n * CR_COMPACT_METRICS 1 to emit each per-attempt compaction `MetricEvent` (retries, bytes, ms, faults) as a\n * JSON line on stdout — pipe to your metrics pipeline. Off by default (cycle summaries\n * still print regardless); the library's `IMetricsSink` seam is what this wires.\n *\n * **Retention (opt-in).** With `CR_RETIRE=1` each cycle also runs {@link retireExpired}, retiring the segments\n * whose `expiresAt` has passed. It is a *separate phase after* compaction, not part of `runCompactionCycle`:\n * compaction's job is to make a segment cheap, retirement's is to delete it, and a destructive step that runs\n * implicitly inside a maintenance cycle is the wrong default for anyone who just wanted their Warm tier drained.\n * Off unless you ask for it, and a custom worker composes the same two calls in the same order.\n * CR_RETIRE 1 to enable the retention sweep (default: off)\n * CR_RETIRE_INTERVAL_MS how often to sweep, independent of the compaction interval (default: 86400000, i.e.\n * daily). Retention windows are measured in days, so sweeping at the 30 s compaction\n * cadence would re-scan the whole registry 2,880 times a day — on DynamoDB that is a\n * full-table Scan each time, billed, competing with the hot path for read capacity.\n * CR_RETIRE_LIMIT max segments retired per sweep (default: 100)\n * CR_RETIRE_DRY_RUN 1 to report what it would retire and delete nothing — start here\n * CR_RETIRE_TOMBSTONE_GRACE_MS ms a retirement's tombstone row must age before the row is deleted\n * (default: 86400000)\n * CR_RETIRE_KEEP_TOMBSTONES 1 to never delete a tombstone row\n * Scope follows CR_COMPACT_NAMESPACE. **Run the sweep from ONE process** — it has no shard option, so N\n * replicas each sweep the whole registry and contend over the same segments.\n */\nimport { SystemClock } from '../system-clock';\nimport { hostname } from 'node:os';\nimport { join } from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport {\n DEFAULT_RETIRE_LIMIT,\n DEFAULT_TOMBSTONE_GRACE_MS,\n LocalFsColdDriver,\n LocalFsRegistryDriver,\n LocalFsWarmDriver,\n retireExpired,\n runCompactionCycle,\n} from '../index';\nimport type {\n CompactionCycleResult,\n CompactionDeps,\n IMetricsSink,\n RetireExpiredResult,\n} from '../index';\n\nexport interface CompactConfig {\n readonly root: string;\n readonly mode: 'once' | 'loop';\n readonly intervalMs: number;\n readonly namespace?: string;\n readonly threshold: number;\n readonly keep: number;\n readonly owner: string;\n readonly shard?: number;\n readonly totalShards?: number;\n readonly maxSegments?: number;\n /** Retention sweep (opt-in) — absent ⇒ the daemon never retires anything. */\n readonly retire?: RetireConfig;\n}\n\nexport interface RetireConfig {\n readonly limit: number;\n readonly dryRun: boolean;\n readonly intervalMs: number;\n readonly purgeTombstones: boolean;\n readonly tombstoneGraceMs: number;\n}\n\n/** Parse + validate config from an environment map. Throws a clear `Error` on misconfiguration. */\nexport function parseConfig(env: Record<string, string | undefined>): CompactConfig {\n const root = env.CR_COMPACT_ROOT;\n if (root === undefined || root === '') {\n throw new Error('CR_COMPACT_ROOT is required (the local-filesystem storage root)');\n }\n const mode = env.CR_COMPACT_MODE ?? 'once';\n if (mode !== 'once' && mode !== 'loop') {\n throw new Error(`CR_COMPACT_MODE must be \"once\" or \"loop\"; got ${mode}`);\n }\n const num = (name: string, def: number): number => {\n const raw = env[name];\n if (raw === undefined || raw === '') return def; // unset OR empty (a common unset-var expansion) → default\n const v = Number(raw);\n if (!Number.isFinite(v) || v < 0)\n throw new Error(`${name} must be a non-negative number; got ${raw}`);\n return v;\n };\n const intOpt = (name: string, min = 0): number | undefined => {\n const raw = env[name];\n if (raw === undefined || raw === '') return undefined;\n const v = Number(raw);\n if (!Number.isInteger(v) || v < min)\n throw new Error(`${name} must be an integer >= ${min}; got ${raw}`);\n return v;\n };\n const shard = intOpt('CR_COMPACT_SHARD');\n const totalShards = intOpt('CR_COMPACT_TOTAL_SHARDS');\n if ((shard === undefined) !== (totalShards === undefined)) {\n throw new Error('set both CR_COMPACT_SHARD and CR_COMPACT_TOTAL_SHARDS, or neither');\n }\n return {\n root,\n mode,\n intervalMs: num('CR_COMPACT_INTERVAL_MS', 30_000),\n namespace: env.CR_COMPACT_NAMESPACE,\n threshold: num('CR_COMPACT_THRESHOLD', 1),\n keep: num('CR_COMPACT_KEEP', 1),\n owner: env.CR_COMPACT_OWNER ?? `${hostname()}:${process.pid}`,\n shard,\n totalShards,\n maxSegments: intOpt('CR_COMPACT_MAX_SEGMENTS', 1),\n retire: env.CR_RETIRE === '1' ? parseRetireConfig(env, num, intOpt) : undefined,\n };\n}\n\nfunction parseRetireConfig(\n env: Record<string, string | undefined>,\n num: (name: string, def: number) => number,\n intOpt: (name: string, min?: number) => number | undefined,\n): RetireConfig {\n return {\n // `intOpt(name, 1)`, not `num`: `num` accepts 0 and 1.5, and `retireExpired` then throws a ValidationError\n // from *inside* the cycle — swallowed into a generic `{\"event\":\"error\"}` line every 30 s in loop mode, so\n // compaction keeps reporting healthy cycles while retention silently never runs. `parseConfig` promises to\n // throw a clear error on misconfiguration; this is what keeps that promise. (CR_COMPACT_MAX_SEGMENTS, the\n // identical concept, already used `intOpt`.)\n limit: intOpt('CR_RETIRE_LIMIT', 1) ?? DEFAULT_RETIRE_LIMIT,\n dryRun: env.CR_RETIRE_DRY_RUN === '1',\n intervalMs: num('CR_RETIRE_INTERVAL_MS', DEFAULT_TOMBSTONE_GRACE_MS),\n purgeTombstones: env.CR_RETIRE_KEEP_TOMBSTONES !== '1',\n tombstoneGraceMs: num('CR_RETIRE_TOMBSTONE_GRACE_MS', DEFAULT_TOMBSTONE_GRACE_MS),\n };\n}\n\n/** Build LocalFs compaction deps rooted at `<root>/{cold,warm,registry}`, optionally with a metrics sink. */\nexport function localFsDeps(root: string, metrics?: IMetricsSink): CompactionDeps {\n return {\n cold: new LocalFsColdDriver(join(root, 'cold')),\n warm: new LocalFsWarmDriver(join(root, 'warm')),\n registry: new LocalFsRegistryDriver(join(root, 'registry')),\n // A real clock, not `{ now }`: outside `core/` ambient time is allowed, and a full clock is what lets\n // the generation write hand the event loop back instead of blocking the daemon for its whole duration.\n clock: new SystemClock(),\n ...(metrics ? { metrics } : {}),\n };\n}\n\n/** Run a single compaction cycle and return the full result (the unit of work for both deploy modes). */\nexport async function runOnce(\n deps: CompactionDeps,\n config: CompactConfig,\n): Promise<CompactionCycleResult> {\n return runCompactionCycle(deps, {\n owner: config.owner,\n namespace: config.namespace,\n threshold: config.threshold,\n keep: config.keep,\n shard: config.shard,\n totalShards: config.totalShards,\n maxSegments: config.maxSegments,\n });\n}\n\n/**\n * Run the retention sweep for one cycle, if configured. Returns `undefined` when retention is off.\n *\n * `now` comes from the deps clock — the same one compaction uses — so a daemon wired with a test clock sweeps\n * against that clock too.\n */\nexport async function retireOnce(\n deps: CompactionDeps,\n config: CompactConfig,\n /**\n * When the sweep last ran (epoch-ms), or `undefined` for \"never\". A sweep is skipped — returning `undefined` —\n * until `CR_RETIRE_INTERVAL_MS` has elapsed, so the retention cadence is independent of the compaction one.\n * `once` mode passes nothing and therefore always sweeps, which is the cron/Lambda shape.\n */\n lastSweptAt?: number,\n): Promise<RetireExpiredResult | undefined> {\n const retire = config.retire;\n if (retire === undefined) return undefined;\n if (lastSweptAt !== undefined && deps.clock.now() - lastSweptAt < retire.intervalMs) {\n return undefined;\n }\n return retireExpired(\n { registry: deps.registry, warm: deps.warm, cold: deps.cold },\n {\n namespace: config.namespace,\n now: deps.clock.now(),\n limit: retire.limit,\n dryRun: retire.dryRun,\n purgeTombstones: retire.purgeTombstones,\n tombstoneGraceMs: retire.tombstoneGraceMs,\n },\n );\n}\n\n/** How many skipped segments one log line names before switching to per-reason counts. */\nconst LOG_SKIPPED_SAMPLE = 20;\n\n/**\n * One JSON line summarising a sweep. Skips are counted per reason AND a bounded sample is named — a silent skip is\n * a lost signal, but the whole list is not loggable: a bad backfill over a 250,000-row fleet would otherwise\n * serialise megabytes into a single line, which is ~78× CloudWatch's 256 KB event limit, so the line that mattered\n * would be truncated or dropped. `retired` and `wouldRetire` are separate fields for the same reason — a counter\n * that means \"deleted\" in one mode and \"would delete\" in another puts phantom deletions on a graph.\n */\nfunction logRetire(result: RetireExpiredResult): void {\n const skipped = result.entries.filter((e) => e.action === 'skipped');\n const byReason: Record<string, number> = {};\n for (const e of skipped) {\n // Collapse `failed: <driver message>` into one bucket; the sample below carries the actual text.\n const key = e.reason.startsWith('failed:') ? 'failed' : e.reason;\n byReason[key] = (byReason[key] ?? 0) + 1;\n }\n const notReclaimed = result.entries.filter(\n (e) => e.action === 'retired' && e.result.generationsRemaining.length > 0,\n );\n log({\n event: 'retire',\n dryRun: result.dryRun,\n scanned: result.scanned,\n eligible: result.eligible,\n retired: result.retired,\n wouldRetire: result.wouldRetire,\n tombstonesPurged: result.tombstonesPurged,\n limited: result.limited,\n skippedByReason: byReason,\n skippedSample: skipped\n .slice(0, LOG_SKIPPED_SAMPLE)\n .map((e) => ({ segment: e.segment, namespace: e.namespace, reason: e.reason })),\n notFullyReclaimed: notReclaimed.slice(0, LOG_SKIPPED_SAMPLE).map((e) => e.segment),\n notFullyReclaimedCount: notReclaimed.length,\n });\n}\n\nconst sleep = (ms: number): Promise<void> => new Promise((r) => setTimeout(r, ms));\nconst log = (obj: unknown): void => {\n process.stdout.write(`${JSON.stringify(obj)}\\n`);\n};\n\n/** A stdout `IMetricsSink` (opt-in via CR_COMPACT_METRICS) — one JSON line per compaction `MetricEvent`. */\nfunction stdoutMetricsSink(): IMetricsSink {\n return {\n onEvent: (event) => log({ event: 'metric', ...event }),\n };\n}\n\n/** CLI entry: parse env, then run one cycle (`once`) or loop until a termination signal (`loop`). */\nexport async function main(env: Record<string, string | undefined> = process.env): Promise<void> {\n const config = parseConfig(env);\n const deps = localFsDeps(\n config.root,\n env.CR_COMPACT_METRICS === '1' ? stdoutMetricsSink() : undefined,\n );\n\n if (config.mode === 'once') {\n const cycle = await runOnce(deps, config);\n log({\n event: 'cycle',\n mode: 'once',\n candidates: cycle.candidates,\n compacted: cycle.compacted,\n deferred: cycle.deferred,\n results: cycle.results,\n });\n const swept = await retireOnce(deps, config);\n if (swept !== undefined) logRetire(swept);\n return;\n }\n\n // loop mode: run forever, one cycle per interval, until SIGINT/SIGTERM.\n let stop = false;\n const onSignal = (): void => {\n stop = true;\n };\n process.on('SIGINT', onSignal);\n process.on('SIGTERM', onSignal);\n log({ event: 'start', mode: 'loop', intervalMs: config.intervalMs, owner: config.owner });\n // `undefined` so the first cycle sweeps; thereafter the retention interval gates it independently of this loop's.\n let lastSweptAt: number | undefined;\n while (!stop) {\n try {\n const cycle = await runOnce(deps, config);\n log({\n event: 'cycle',\n candidates: cycle.candidates,\n compacted: cycle.compacted,\n deferred: cycle.deferred,\n results: cycle.results,\n });\n const swept = await retireOnce(deps, config, lastSweptAt);\n if (swept !== undefined) {\n lastSweptAt = deps.clock.now();\n logRetire(swept);\n }\n } catch (err) {\n log({ event: 'error', message: (err as Error).message }); // a cycle error must not kill the daemon\n }\n if (!stop) await sleep(config.intervalMs);\n }\n log({ event: 'stopped' });\n}\n\n// Run only when invoked directly (not when imported by tests). `process.argv[1]` is this file when run as a bin;\n// `pathToFileURL` builds a spec-correct file:// URL (drive letters, spaces, UNC paths) for a robust compare.\nif (process.argv[1] !== undefined && import.meta.url === pathToFileURL(process.argv[1]).href) {\n main().catch((err: unknown) => {\n process.stderr.write(`${(err as Error).message}\\n`);\n process.exit(1);\n });\n}\n"]}
|
package/dist/cassandra/index.cjs
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var cassandra = require('@cloudbitmaps/core/cassandra');
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
Object.keys(cassandra).forEach(function (k) {
|
|
8
|
-
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
|
|
9
|
-
enumerable: true,
|
|
10
|
-
get: function () { return cassandra[k]; }
|
|
11
|
-
});
|
|
12
|
-
});
|
|
13
|
-
//# sourceMappingURL=index.cjs.map
|
|
14
|
-
//# sourceMappingURL=index.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.cjs","sourcesContent":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from '@cloudbitmaps/core/cassandra';
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from '@cloudbitmaps/core/cassandra';
|
package/dist/cassandra/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.js","sourcesContent":[]}
|