* feat: pending event deliveries and delivery-class invariants (PUT-1676)
* fix: make pending delivery claims and drains atomic, keep the region under its ceiling (PUT-1676)
- claim() and the drain-time reindex run as Lua over the subscription's own
{subId}-tagged keys. Two claimers can no longer both lease the head, and a
drain that finds the queue empty deletes it in the same step it checks, so a
concurrent enqueue is never wiped between the two.
- An append writes the entry and its queue position in one MULTI (same slot),
with the index seeded before it and corrected after, so an entry is never
visible without its position and never left out of the sweeper's index.
- Pipelines no longer mix slots (index/counter vs. per-subscription keys), so
the store works on a multi-shard cluster, not only a single-shard one.
- Region shedding counts the marker it leaves behind; it used to stop one over
the ceiling and convert a real event into a marker on every enqueue after.
- A claimed or suspended subscription moves to the back of the sweeper's index,
so a delivery nobody settles cannot hold the head against every other backlog.
- `single` rows must carry a `worker` target: with sockets exhausted and no
handler, an unacknowledged delivery would sit at the head forever.
- A gap marker for a row with no socket target is dropped rather than counted
as a delivery of nothing.
- Backlog keys carry a 7-day TTL, refreshed by every claim, as a backstop for
keys a purge/enqueue race left unindexed.
Puter.js
Learn More · Docs · Tutorials · Examples · X
Puter.js gives you auth, cloud storage, database, AI, and more through a single JavaScript library. It is the go-to backend for AI-generated apps.
There is nothing to configure, no API keys, no infrastructure to set up, whether you write the code yourself or have your AI tool do it. Tools like Claude Code, Codex, OpenCode, Lovable, and Replit can generate complete, production-ready apps in a single shot with fewer AI tokens.
Installation
NPM:
npm install @heyputer/puter.js
CDN:
Include Puter.js directly in your HTML via CDN in the <head> section:
<script src="https://js.puter.com/v2/"></script>
Usage
Browser
ES Modules
import {puter} from '@heyputer/puter.js';
// or
import puter from '@heyputer/puter.js';
// or
import '@heyputer/puter.js'; // puter will be available globally
CommonJS
const {puter} = require('@heyputer/puter.js');
// or
const puter = require('@heyputer/puter.js');
// or
require('@heyputer/puter.js'); // puter will be available globally
Node.js (with Auth Token)
const {init} = require("@heyputer/puter.js/src/init.cjs"); // NODE JS ONLY
// or
import {init} from "@heyputer/puter.js/src/init.cjs";
const puter = init(process.env.puterAuthToken); // uses your auth token
const puter2 = init(process.env.puterAuthToken2); // use some other auth token
Node.js (with Auth Token + Web Login)
const {init, getAuthToken} = require("@heyputer/puter.js/src/init.cjs");
// or
import {init, getAuthToken} from "@heyputer/puter.js/src/init.cjs";
const authToken = await getAuthToken(); // performs browser based auth and retrieves token (requires browser)
const puter = init(authToken); // uses your auth token
Usage Example
After importing, you can use the global puter object:
// Print a message
puter.print('Hello from Puter.js!');
// Chat with GPT-5 nano
puter.ai.chat('What color was Napoleon\'s white horse?').then(response => {
puter.print(response);
});
Starter Templates
You can also use one of the following templates:
- Client-side projects: Angular, React, Next.js, Vue.js, Vanilla.js
- Node.js + Express: Node.js + Express template
Setting Custom Origins
By default puter.js uses the official Puter API and GUI origins. You can customize these origins by setting global variables before importing the SDK like so:
// For API origin
globalThis.PUTER_API_ORIGIN = 'https://custom-api.puter.com';
// For GUI origin
globalThis.PUTER_ORIGIN = 'https://custom-gui.puter.com';
import {puter} from '@heyputer/puter.js'; // or however you import it for your env
Documentation & Community
License
Apache-2.0