Limits and errors
Limits
The limits an app's calls are held to. A running app can read the numbers
of the Tinylib it's running on from platform.limits.
| Limit | Value | Description |
|---|---|---|
data.keyLength | 128 characters | |
data.valueBytes | 64 KB | One value, as JSON. In a private app, measured before encryption. |
data.keysPerApp | 500 | |
data.appBytes | 1 MB | All of a user's values in the app added together, each measured as for valueBytes. |
notifications.titleLength | 80 characters | |
notifications.bodyLength | 300 characters | |
notifications.perDay | 20 | Scheduled in any 24 hours. |
notifications.waiting | 50 | Scheduled and not yet sent. |
notifications.aheadDays | 30 days | How far ahead at can be. |
shared.keys | 32 | |
shared.valueBytes | 4 KB | One value, as JSON. |
shared.bytes | 16384 | All of the values added together, each measured as for valueBytes. |
shared.page | 50 | The most people one list returns. |
shared.pageDefault | 25 | The people one list returns when it names no limit. |
rooms.maxMembers | 6 | The most members a room can have. server.js's size can be smaller. |
rooms.perPerson | 20 | Rooms of one app a person can be in at once: rooms they haven't left that haven't ended. Past it, createRoom and a join are refused with too_many_rooms. host.rooms() answers at most this many rooms: every one that hasn't ended, then ended ones. |
rooms.openInvites | 20 | Invites one person has open in one app's rooms at once, from the sheet and by id. An invite past it is refused with too_many_invites. |
rooms.stateBytes | 128 KB | A room's state from server.js, as JSON. A change that goes over it is refused with too_big. |
rooms.viewBytes | 64 KB | What view returns for one member, as JSON. A change that goes over it is refused with too_big. |
rooms.argsBytes | 16 KB | The arguments of one act, as JSON. |
rooms.optionsBytes | 16 KB | The options host.createRoom gets, as JSON. |
rooms.memberEntries | 32 | Entries in a room's members, people who left included. A join past it is refused with full. |
rooms.idleDays | 7 days | When server.js exports turn, a room that stores no change for this long runs left for each member turn names, and ends when turn then names nobody. |
rooms.callsPerSecond | 20 | room.act calls one member makes in one room each second. A call past it is refused with too_many_calls. |
rooms.endedDays | 30 days | How long an ended room's data stays readable before it's deleted. |
rooms.retryAfterSeconds | 60 | How long a room's change waits after an ask before the Worker's every-minute cron asks again (record 0030). |
rooms.retryBatch | 50 | Rooms the Worker's every-minute cron asks to take their changes in one run, the longest waiting first (record 0030). |
server.cpuMs | 0.05 seconds | CPU time one call into server.js can use. |
server.waitMs | 10 seconds | Time one call into server.js can take, waiting included. |
server.messageLength | 300 characters | The message ctx.refuse gives. Its code is held to data.keyLength. |
server.logLinesPerCall | 20 | Lines of console output kept from one call. |
server.logLineLength | 500 characters | Characters kept of one line of console output. |
private.unlockMinutes | 15 minutes | Tinylib closes a private app this long after unlocking it. |
calls.timeoutMs | 15 seconds | A call Tinylib hasn't answered by then rejects with timeout, except calls that wait on the user, act and leave. The room refuses an act it hasn't finished by then with failed. |
Errors
ErrorCode
type ErrorCode =
| "outside_host"
| "timeout"
| "failed"
| "signed_out"
| "offline"
| "invalid_key"
| "invalid_value"
| "value_too_large"
| "too_many_keys"
| "too_much_data"
| "private_app"
| "unreadable"
| "invalid_notification"
| "denied"
| "too_many_notifications"
| "too_many_waiting"
| "too_many_rooms"
| "too_many_invites"
| "not_member"
| "needs_tap"
| "too_many_calls"
| "too_big"
| "refused"
| "not_your_turn"
| "not_started"
| "too_few"
| "unknown_action"
| "not_removable"
| "ended"
| "full"
| "no_invite"
| "not_joinable";
The reasons a call can reject.
| Code | From | When |
|---|---|---|
outside_host | every call | The page isn't running inside Tinylib. |
timeout | every call but act, leave and those that wait on the user | Tinylib didn't answer within limits.calls.timeoutMs. |
failed | every call | Something went wrong on Tinylib's side, or server.js threw or took too long. Try again. |
signed_out | createRoom, rooms(), a room's calls, notifications.schedule, cancel, list | Nobody is signed in. After a click or a tap, Tinylib asks the user to sign in first, and the call rejects when they don't; signing in opens the app again. |
offline | createRoom, rooms(), a room's calls, notifications.schedule, cancel, list, friends.list, public.list | No connection. |
invalid_key | data, friends, public | The key is empty or over the length limit. |
invalid_value | every set, createRoom, act | The value can't be turned into JSON. |
value_too_large | every set | The value is over the limit for its store. |
too_many_keys | every set | The key is new and the store already holds the limit. |
too_much_data | every set | The values in the store would add up to more than the limit. |
private_app | friends, public | The app is private, and has no audience stores. |
unreadable | data.get, data.getAll | A private app's value won't decrypt. |
invalid_notification | notifications.schedule | A field is missing or over its limit, or at isn't a time. |
denied | notifications.schedule | The user said no to this app's notifications. The switch on the app's page changes that. |
too_many_notifications | notifications.schedule | The daily limit is used up. |
too_many_waiting | notifications.schedule | The limit on notifications waiting to be sent is reached. |
too_many_rooms | createRoom | The user is in limits.rooms.perPerson rooms in this app that haven't ended. |
too_big | createRoom, act | options or args is over its limit, or the action would take the state or a view over its limit. See limits.rooms. |
refused | act | server.js called ctx.refuse. The message is its sentence. |
not_your_turn | act | turn doesn't name the user. |
not_started | act | The game hasn't started. |
too_few | start | Fewer than players.min are in the game. |
unknown_action | act, start | server.js has no action by that name, or start was called in a shared room. |
not_removable | act | The action called ctx.remove with the user's own id, a member who left, someone never in the room, or an id it already removed. |
not_member | a room's calls | The user left the room, or it was deleted. |
ended | act, start, invite, an invite's join | The room has ended, so nothing can change it. |
full | invite, an invite's join | Every place in the room is taken, or the game has started. |
too_many_invites | invite | The user would have more than limits.rooms.openInvites invites open in this app. |
no_invite | an invite's join | The invite stopped: its sender left, or the user declined it on another device. |
not_joinable | an invite's join | server.js's joinable turned the user away, or a block keeps them out. |
needs_tap | invite, an invite's join and decline, notifications.schedule | The call didn't follow a click or a tap. For notifications.schedule, also when the user closed the sheet without answering. |
too_many_calls | act, start | The user acted in the room more than limits.rooms.callsPerSecond times this second. |
CallError
What a refused call rejects with. Branch on code. For each of Tinylib's
codes, the message is the sentence a person reads, and a page can show it
as it is; its wording can change. When Tinylib knows more about what went
wrong, it writes that to the console. refused carries the sentence
server.js passed to ctx.refuse.
Example
try {
await host.data.set('big', 'x'.repeat(70 * 1024))
} catch (error) {
if (error.code === 'value_too_large') splitIntoPages()
}
Extends
Error
Properties
| Property | Type |
|---|---|
code | ErrorCode | string & object |