Every non-silent notification write and in-place update emits a node-local
`notif.written` event. PushService picks it up when push is enabled and a
provider is registered, and sends it to the user's devices unless the user
is connected where the notification already shows.
- `app.message` needs the user's push consent for that app and reaches
Puter's devices plus that app's; every other type follows the user's Puter
preference and reaches Puter's devices only.
- Presence counts this node's sockets, and other nodes and regions where
presence is kept.
- Providers register per platform with `registerProvider`; core ships none.
Batches of 100 tokens, bounded concurrency, no retries. Delivered devices
are touched, unregistered ones removed, others get a failure counted.
- Messages are built per type and fit to a 3,800 byte budget; `data` is
never cut.
POST, GET and DELETE /push/devices on the api subdomain let a signed-in
Puter session register, list and remove its account's push devices. Apps,
access tokens and worker sessions get 403. Registration answers 503
push_disabled unless push.enabled is set; listing and removal always work.
An account keeps at most 20 devices, and a new one removes the least
recently seen. Responses never include the device token.
Delivery skips devices whose session is revoked, expired or gone; devices
with no session still receive. A token that changes owner gets a new uid
and created_at, and a register that keeps losing the token to another
user ends in a 409. touch and recordFailure match the owner as well as
the uid, listByUser reads from the primary, the stale sweep stops between
batches once shutdown starts, and the user agent and label limits are
exported.
Adds the push_device table on SQLite, MySQL and Postgres, a store for
registering, refreshing, listing and removing devices, and a push service
that removes devices when their session is revoked or when they go unseen
past push.deviceRetentionDays (default 60). Devices go with their account
through the user foreign key.