{"_id":"@bradensbay/globals-shm","_rev":"2-f4f6f58c45f13d85daa3f115c429f56b","name":"@bradensbay/globals-shm","dist-tags":{"latest":"0.2.1"},"versions":{"0.2.0":{"name":"@bradensbay/globals-shm","version":"0.2.0","license":"MIT","_id":"@bradensbay/globals-shm@0.2.0","maintainers":[{"name":"christiangrrogers","email":"christiangrrogers@gmail.com"}],"homepage":"https://github.com/christianGRogers/globals#readme","bugs":{"url":"https://github.com/christianGRogers/globals/issues"},"dist":{"shasum":"3c15dea5682eb330b8508478697329522e23c845","tarball":"https://registry.npmjs.org/@bradensbay/globals-shm/-/globals-shm-0.2.0.tgz","fileCount":14,"integrity":"sha512-MLffxwiw3lQzsNNpn/SNXR0FkJvbVO8tHAB31BN0FpQV3PJ0C3QkotwJ2+csE+visAkPp5N/ffuulvHrx3qtSg==","signatures":[{"sig":"MEUCIQCS3iyIszFA/ZfUHtP/XZvlADA1z40pVNyez5BFcpkywgIgb5lpScUnq76HsMYDzOZmXSlLtTFcSHRVzlyyM/GDVio=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@bradensbay%2fglobals-shm@0.2.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":431529},"main":"./dist/src/index.js","type":"module","types":"./dist/src/index.d.ts","engines":{"node":">=20.11.0"},"exports":{".":{"types":"./dist/src/index.d.ts","import":"./dist/src/index.js"}},"gitHead":"21dd602e24b18673ff60a164f2556eb927bb6596","scripts":{"build:native":"cd native && node-gyp rebuild"},"_npmUser":{"name":"christiangrrogers","email":"christiangrrogers@gmail.com"},"repository":{"url":"git+https://github.com/christianGRogers/globals.git","type":"git","directory":"packages/shm"},"_npmVersion":"10.9.8","description":"The native transport: one file-backed shared memory region, a double-buffered owning writer, and reader copies that are always exactly one commit, through Node-API so the V8 memory cage is never involved.","directories":{},"_nodeVersion":"22.23.2","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/globals-shm_0.2.0_1788028657906_0.141863806392865","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"@bradensbay/globals-shm","version":"0.2.1","description":"The native transport: one file-backed shared memory region, a double-buffered owning writer, and reader copies that are always exactly one commit, through Node-API so the V8 memory cage is never involved.","type":"module","main":"./dist/src/index.js","types":"./dist/src/index.d.ts","exports":{".":{"types":"./dist/src/index.d.ts","import":"./dist/src/index.js"}},"scripts":{"build:native":"cd native && node-gyp rebuild"},"engines":{"node":">=20.11.0"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/christianGRogers/globals.git","directory":"packages/shm"},"_id":"@bradensbay/globals-shm@0.2.1","gitHead":"b64920872c82a9a84c5dca28dfa39a6bee9c3983","bugs":{"url":"https://github.com/christianGRogers/globals/issues"},"homepage":"https://github.com/christianGRogers/globals#readme","_nodeVersion":"22.23.2","_npmVersion":"10.9.8","dist":{"integrity":"sha512-H8GVCVCUrDgPBvuV+SJK0n2Vupn/JNIa+zk5nqrbiCpO/yKzOVt8K1DwDUh5MKANmktYVCeoQEbwYFOYTXQApw==","shasum":"781383147283895329600c57846ff04814146d0d","tarball":"https://registry.npmjs.org/@bradensbay/globals-shm/-/globals-shm-0.2.1.tgz","fileCount":14,"unpackedSize":431529,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@bradensbay%2fglobals-shm@0.2.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIEyH45AvmyP5gjnI6Wso8H9R+ci/yCBc/Xj0DFP7VfNNAiEAqzn8TnFnc5nPhewInb2bn14LEeIXQgg3JC4mt9wBLpw="}]},"_npmUser":{"name":"christiangrrogers","email":"christiangrrogers@gmail.com"},"directories":{},"maintainers":[{"name":"christiangrrogers","email":"christiangrrogers@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/globals-shm_0.2.1_1788134560865_0.12146347509570421"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-29T18:37:37.668Z","modified":"2026-08-31T00:02:41.401Z","0.2.0":"2026-08-29T18:37:38.032Z","0.2.1":"2026-08-31T00:02:41.034Z"},"bugs":{"url":"https://github.com/christianGRogers/globals/issues"},"license":"MIT","homepage":"https://github.com/christianGRogers/globals#readme","repository":{"type":"git","url":"git+https://github.com/christianGRogers/globals.git","directory":"packages/shm"},"description":"The native transport: one file-backed shared memory region, a double-buffered owning writer, and reader copies that are always exactly one commit, through Node-API so the V8 memory cage is never involved.","maintainers":[{"name":"christiangrrogers","email":"christiangrrogers@gmail.com"}],"readme":"# @bradensbay/globals-shm\n\nThe native transport: one file-backed shared memory region, an owning writer that\nalternates between two data slots, and reader copies that are always exactly one commit,\nthrough Node-API. This is the layer [ADR 0003](../../docs/adr/0003-native-transport.md)\nadopts, and the productionised descendant of\n[spike 08](../../spikes/08-mmap-accessor/README.md).\n\nThe double buffering is load bearing, and the transport soak is why. A single-slot seqlock\nholds its lock for the whole flush copy, so a writer at full rate on a large region leaves\nstable windows barely longer than a reader's own copy, and a reader can retry into\nlivelock; the soak caught exactly that. With two slots, the writer builds each commit in\nthe slot the last commit did not publish, each slot carries its own sequence and version,\nand a reader's copy is torn only if the writer laps into the same slot mid copy, which it\ncannot sustain because it must complete a whole further commit first.\n\n## The contract\n\n- **One owner per region.** The process that created the region is the only one that may\n  flush. A flush copies the commit's dirty ranges from the owner's private mirror into the\n  mapping inside one seqlock section and bumps the version.\n- **Readers copy, then decode.** `sync(dest)` produces a copy of the whole data region that\n  is one commit and never a torn mixture, and returns the version it belongs to, which under\n  a fast writer may be newer than the version observed at the start of the call. `version()`\n  is one native call, the fast path a caller checks before deciding to sync.\n- **Nothing outside this package touches shared memory.** No ArrayBuffer ever wraps the\n  mapping, which is what keeps the V8 memory cage out of the picture. Every byte a caller\n  decodes lives in a buffer V8 allocated.\n- **Version zero means empty.** A freshly created region has version 0 and undefined data;\n  the first flush makes it readable.\n- A region file carries a magic number and `LAYOUT_VERSION`; attaching to a foreign file or\n  a layout this build does not understand fails closed with a typed error (`ESHM_MAGIC`,\n  `ESHM_LAYOUT`). Misuse fails the same way: `ESHM_BOUNDS`, `ESHM_OWNER`, `ESHM_CLOSED`,\n  `ESHM_LIVELOCK`.\n\n## Usage\n\n```ts\nimport { OwnerRegion, ReaderRegion } from \"@bradensbay/globals-shm\";\n\n// The owning process, once:\nconst owner = OwnerRegion.create(path, 1 << 20);\nconst mirror = new Uint8Array(owner.dataSize);\n// ... write a commit into the mirror, then publish the dirty ranges:\nowner.flush(mirror, [[0, 64], [4096, 512]]);\n\n// Any other process:\nconst reader = ReaderRegion.attach(path);\nconst copy = new Uint8Array(reader.dataSize);\nlet held = 0;\nfunction read(): Uint8Array {\n  if (reader.version() !== held) held = reader.sync(copy);\n  return copy;\n}\n```\n\n## Building\n\nThe addon builds with `npm run build:native` at the workspace root, which needs a C\ntoolchain and Python for node-gyp. The `binding.gyp` lives in `native/` rather than the\npackage root deliberately, so npm does not auto-build it on every install; prebuilt binaries\nare planned before any release (see [plan-native.md](../../docs/plan-native.md), N1).\n\n## Measured behaviour\n\nFrom spike 08 on the reference machine (macOS arm64, Electron 33): a `version()` call costs\nabout 14 ns, a 1 MB `sync` about 16 µs, and a real IPC round trip 35 to 40 µs. The\ncross-process test in this package holds the same bar the arena's soak does: a writer\nflushing at full rate from another OS process, zero torn copies observed.\n","readmeFilename":"README.md"}