Sources
Docs: Perceptions, Plots, Policies, and Preferences. Web App: Select a Pane and open Programming, Palette, Policies, Preferences, Plots, or Panes in its editor drawer.Structure
A Pane carries its Perception and its Policies, and it owns a Palette and its Plots. Adding a Pane opens a dialog that asks for its name, one sentence on what it is for, and an icon; every Pane needs a description, shown in the band under its header. The Perception declares the Pane’s one type, what it shows and what people save on it, and its references to other Panes. Its React source renders the Pane; SQL Plots read or calculate data. Referencing another Pane does not move the Pane or copy its saved rows. There are four kinds of Pane (Kinds of Pane):- A Plot Pane owns the Plots it draws. Its type, in scalar-lib types, is the kind of the rows of the one Plot its Perception does not declare. Each other Plot declares its own contract. A computation that other Panes read, or that has its own lifecycle, gets a Pane of its own, and the Plots that need it read it by name.
- A bound Pane has no SQL. One field of its parent’s row feeds it as
props.value, and it uses its parent’s Policies (Bound Panes). - A saved-data Pane has no SQL. Its type has an
idfield, and the values people save on it are Preferences: rows of its type, one for each item and each actor. A Plot on a saved-data Pane would make it a Plot Pane that refuses every save of a row, so the saved-data-plot rule refuses it. Give the Plot a Pane of its own. - A layout Pane has a null type, so it holds no saved rows.
PA-AU-049, naming the Pane and those Plots. A Pane the published Version already holds that way is
history: its Warnings & Errors show it as info, which never blocks, and every
other change still saves and publishes.
A Pane reads at most 10,000 rows from a Plot. Read only what it draws: a chart
or a total reads rows its Plot’s SQL has already aggregated, heavy work is read
from a stored output, and a table a person browses reads a page at a time. See
Large results.
The editor drawer has one tab for each part:
A Page has the same drawer, with a Plots tab that lists only its Panes’
Plots, because a Page owns none. The tab that holds the React source is
Programming on both, the name the Policies tab gives the code. Switching tabs keeps each draft. Moving
to another Pane or Page keeps the drawer open or closed and on the same tab, so
a Pane’s Policies opens on the next Pane’s Policies. A Piece without
that tab opens on its first tab. In a drawer too narrow for every tab’s name,
the tabs other than the open one show their glyph alone, and name themselves
on hover. In Auto
the preview shows a Pane as a card centred on the canvas, as tall as what it
draws.
A missing or hidden source does not remove the Pane or its other tabs. The source
editor shows Source unavailable, and a Plot remains listed even when its SQL
is hidden. An allowed compiled Page or Pane still renders when its React or
Perception source is hidden. Its declared Pane references remain available.
Unsaved source edits use the editing preview until a matching build is available.
An unsaved Perception or Policies change is not code the preview runs, so the
compiled preview stays on the canvas while it saves.
When Ponder takes a picture of a Pane, it uses the light or dark theme shown
when you sent the Message, including your system theme when you follow it.
A later theme change applies to new pictures; images already in the
conversation keep the appearance in which they were captured.
The host supplies these React props:
A referenced Pane that throws while it loads or renders shows Couldn’t
populate with its name and the error’s message in its place. The Page or Pane
that mounted it and its other Panes keep rendering. When the Page or Pane on
screen itself throws, the frame shows the same card.
policies.capabilities.edit.preferences decides whether an editing action is
enabled. Keep a control the requester cannot use on screen, disabled, with
why: when seatCapabilities allows it, switching to their fullest
participation mode turns it on; otherwise say who can. Hide only what a view
capability or a filter Policy keeps from them.
Add no other copy. A label names its control or value in the fewest words. A
Pane adds no sentence that explains a control, says where a value came from,
tells the reader they can change something, or repeats what a control already
shows. A disabled control’s reason, the reading, empty, cut-off and error
states, and the sentences
ImproveParable and PopulateParable
carry are not extraneous: the reader needs them to act.
A true capability describes participant eligibility;
capabilities.conditional means actual values or rows may still need condition
checks: it is true when a filter Policy covers
the Pane, from its holder’s tree, the line’s root Page for a Pane nothing
declares, or the Pane’s own Plots, and does not let this requester read every
row. It does not look at what the Pane’s Plots read. A filter narrows only a
Plot that reads Provider data, so a Pane whose Plots read only saved rows,
Workspace tables or literal values reads in full even when conditional is
true.
capabilities.writeConditional is true when a filter Policy for create,
edit or delete binds this requester’s writes of the Pane’s shared rows
(This Parable’s and every team’s): the write is checked against the filter’s
conditions and may be refused by its value. It is never true for the Primary.
When it is false, the requester’s shared writes in the Pane pass every
filter; when it is true, a Pane can enable a control only for the rows a
Plot of its own says the requester may change, and say why the others are off.
Neither boolean nor authorityKey authorizes a later request.
When the host reads a Pane’s Policies again, after a row that a Policy reads changes or a write
is refused, the decisions on screen stay until the new ones arrive, which then
apply at once, a lost permission included; a control a capability gates does
not blink out meanwhile. A Pane given another input is denied everything until
that input’s decisions arrive.
policies.admissions says, for each action and part the requester may take,
which grant admitted them: by is participation (with the grant’s lowest
listed level their seat meets), person, or role (with roleId and
roleName), and setting names the saved row whose value was the grant,
when one was. parable names the other Parable when the requester’s
participation there admitted them (participantsOf). A refused action and part has no entry. viewAs is true
under a View as preview, where grants admit by participation alone.
policies.seatCapabilities is present only while the page works in a
participation mode below the seat the requester holds (under View as, the
previewed person’s), such as a Publishing author in Peeking. It holds the
decisions at that seat, in the shape of capabilities, while capabilities
holds the mode’s. At the seat, and in a mode at or above it, it is absent. It
never authorizes anything: the server refuses a change the mode does not
allow, whatever seatCapabilities says.
Use @parable/<parable>/<pane> for Props, Item, Row, key, namedType, namedTypes, preferences,
data, propose, plots, panes, plotApi, pages, getParableContext(), and useParableContext(), which
renders again when the host sends a new context. These bindings use the saved
Perception and declared Plot contracts. namedType is the named type the Pane shows, as its
Perception declares it, or null when it shows none, and namedTypes holds every named type
the read describes, by key (Read a named type at runtime). Other application components enter through declared Pane
references; the approved React, Motion, Kysely, scalar, and shared-control
libraries remain available. Only a Page is composition only: its code may import
only the Panes it declares and the runtime layout modules. A Pane whose
type is null owns no undeclared Plot, but can still use the shared controls and
read the Plots of the Panes it declares.
Warnings & Errors
Every check reports a warning or error in a Page’s, Pane’s or Plot’s code the same way: what it is, the check that found it, its rule or code, and its line and column.
The editor underlines each warning and error and marks its line in the
gutter. Hovering it shows its message, its rule, and any fix as a button. A fix
labelled changes behaviour can change what the code does; read it before
applying it. The footer under every code editor lists the Warnings & Errors.
Folded, it shows a count for each severity, or No Warnings & Errors. Opened,
it lists each one with the check that found it and its line and column, errors
first; choosing one moves the editor to that line. The footer stays open or
folded as you move between Pieces, and each editor tab shows how many errors and
warnings its document has.
Warnings & Errors never block a save, and viewing a Parable never waits on them.
Publishing does: a Publish refuses Changes while any Page, Pane or Plot in them
has a warning or an error, and the refusal names each one and its counts. The
Publish button says how many there are before you press it. Info findings never
block. No code publishes unchecked: a file over 256 KB is too large to check,
and a Publish refuses it until it is made smaller or split into more Panes; a
file whose check could not finish is refused until a later Publish finds it
checked.
The code check, TypeScript and the build describe the text that was saved. Once
you type, their underlines clear until the next save, and the editing preview
reports errors in the text you typed. Checking for Warnings & Errors… means a
result is not ready yet, and Warnings & Errors could not be checked gives the
reason; neither means the source is clean. The checks run when a Piece is
saved, at Prepare and at Publish, and when Ponder reads a Piece’s problems;
opening a Piece shows the result of the last check and never runs it again.
A file that no check has answered since the checks changed shows Checking
for Warnings & Errors… until the next save or Publish. The checks run in
every Workspace. Where one cannot run, the Piece API reports each checked file
as
failed with the reason, so an agent never takes it for clean, and a
Publish waits until the check runs.
A Pane that does not build
Each Page and Pane compiles on its own. A Pane that does not build draws This Pane did not build and its first error where it would be, and the rest of the Page renders around it. Selected alone, it shows … did not build on the canvas, with every error listed under its code. Publishing refuses Changes in which any Page or Pane does not build.Fixing Warnings & Errors with Ponder
Ponder reads and fixes Warnings & Errors with two tools. Read a Piece’s problems returns one Piece’s documents, its code and its Palette, each with its exact text, that text’s revision, and every current warning and error from the code check, TypeScript, the build and Plot SQL validation, with line, column, offsets and the text of the line.pending is true while a check has not answered for that text.
For a Page or Pane it also returns the Perception source and the Policies, so
Ponder reads one Piece whole without reading the whole Parable; Policies are
left out for anyone without view permission on Policies. Ponder reads a whole
Parable as an outline of its Pieces, with no code.
Edit part of a Piece’s source replaces exact passages of one document. Each passage must
occur exactly once in the text, or nothing is saved and the refusal
(PA-AU-045) says how many times it occurs. The edit is refused (PA-AU-002)
when the document changed after it was read, so it never lands on text Ponder
has not seen. Its answer carries the new revision and every warning and error
after the save.
A refused save tells Ponder which Piece, import or handle is at fault and its
line and column, never the submitted code. When Ponder previews a Pane that does
not build, the answer names the first error and the Pane to read. The Panes and
Plots Powers teach the loop: read the Warnings & Errors, make the smallest edit
that fixes one, and read them again.
Every read and save of a Parable’s contents returns the same Warnings & Errors:
the code check and TypeScript, or a Plot’s recorded validation, and the build.
Checking that Panes draw
Check a Pane (check_pane) tells Ponder which Panes do not draw, without
a browser. It reads the given Changes, or the Parable’s own content, and
checks the named Panes, or every Pane. For each Pane it reports:
placed: false when no Page shows the Pane (the unplaced-pane note).drawsWithoutInput: false when the Pane waits for a value that no parent hands it (the needs-input note), andacceptsNullfrom its runtime binding.resolution: what panes/resolve gives the Pane with no Preference selected, or why it refuses the Pane.plots: the rows each Plot of the Pane returns, at most 50 for each Plot, and at most 20 Plots for each check. A read that fails gives its reason. A Plot that takes inputs uses its saved parameters. When it has none, the check reads it with null for each input.diagnostics: the counts that Read a Piece’s problems reads.
diagnostics is still a problem. A Plot whose read fails is
still a problem. clean is true when no Pane has a problem and no check
is pending. placed and drawsWithoutInput are null while the lint of the
Pane’s code has not answered. When that lint could not run, they are null
and the Pane has a problem that gives the reason. When the read has no
checked code for the Pane, because it has no code or the reader may not see
its code, they are null and the Pane has a problem. The check does not find
code that throws while it draws or a broken layout. The Pages Power tells Ponder to end a build only when the
check is clean. When Check a Pane is available to Ponder, the answer of each
completed Edit Pieces or Edit part of a Piece’s source call gives a
nextStep: call Check a Pane with that Parable and its Changes. A check that
is not clean gives a nextStep too: fix each problem it names, then call
Check a Pane again with the same arguments. An edit whose outcome is unknown
gives a nextStep that names the read to make before any new edit: the
Piece, the Changes or the Parable that the edit named.
Services
Render a referenced Pane with an inlineprimitive of its type, or with
none. The host resolves the selection and supplies composition, owned Plots,
and current policy decisions. Caller props cannot replace those decisions or
bindings. A null-compatible Pane can render without a selected value; other
Panes stay unfilled. Parable never picks a saved row on its own. A Pane reads
its rows through preferences (Preferences),
its own data through data, and changes the Parable only through propose,
which the reader confirms. A bound Pane receives its value as props.value
from its parent’s row, so it needs no read of its own. Its saved rows arrive
with the Pane’s load when its Perception sets preload, and later saves, by
anyone, update them in place.
The server resolves Panes in bounded batches.
A refused item does not discard permitted siblings. The host can also request
capabilities alone without receiving values, source, bindings, or private schema.
A compiled Page also keeps rendering when a declared Pane’s module is withheld
from its reader. That Pane shows This Pane is unavailable in its place;
the Page and its permitted siblings remain visible. A root Page without its
own compiled module is still an error.
Ordinary React state and Context coordinate inputs and charts without saving
every change. A declared Pane’s module exposes its React exports as a Promise;
React.use(panes.state.module) lets referenced Panes share an exported Context.
Data refreshes and Current/Report changes do not need to recreate that state.
Changing the requesting actor or Workspace replaces the renderer’s context.
Storage
A Pane’s Perception and Policies are fields of the Pane, saved and versioned with it. Its Palette and its Plots are Pieces the Pane owns. Creating a Pane creates its Palette, and deleting a Pane deletes its Palette and its Plots. Deleting a Pane is refused while another Page or Pane still uses it: one whose Perception declares it, or whose code reads one of its Plots. The refusal names them; change or remove them first. Reads never create rows or repair missing configuration. A Pane keeps a choice only when its code saves a row; see Preferences. A read layers a person’s own row (Me), This Parable’s and the Parable’s Default, field by field. A Page is composition only. Its type is null; it arranges referenced Panes that own application values and queries.Security
Using a Pane and its selected value requires currentview.preferences access.
Inspecting its Perception, Plot source, CSS, or Policies uses the
corresponding view target. Permission to inspect source is not required merely
to render an allowed Pane or read permitted SQL output.
A permitted renderer receives executable JavaScript and CSS. Source-editor
restrictions cannot make delivered assets secret. SQL source can remain private
because named execution resolves it on the server. Every query and stored write
checks current Policies independently of what the component displays.
What a Pane’s code can reach
A Pane’s compiled React runs in the reader’s browser inside a sandboxed frame with an opaque origin. That frame has no forms, no downloads, no pop-ups, no network access, and no remote scripts; everything it renders is inlined. Because the frame has no forms, a form’s submit never runs its handler: handle the button’s click and the field’s Enter instead. The Code check warns about a form’sonSubmit or action and a button’s formAction. The frame’s
only way to the application is the host bridge, which answers requests that
name a live Page or Pane of the mounted Parable (its value, its saved rows and
its Plots) or the Parable’s files
(Files in Pane code) under the reader’s own
permissions, at a bounded rate. The Workspace’s files are the one exception:
their own rules decide (The Workspace’s files). The
bridge starts
the actions below only after a press. A Pane’s module names that Pane and the
Panes it declares, but one frame renders a whole Page, so the host cannot tell
which Pane’s code sent a request: Pane code can reach any Pane of the Parable
the reader can, not only its own. The
bridge also carries what the frame draws but cannot fetch: Font Awesome glyphs,
and the company logos BrandLogo
shows, which the host fetches through the app and hands over as image data. A
Pane can preview SQL of its own in place of a Plot’s (plotApi.preview) in the
Piece editor’s canvas and on a Page in Ponder’s chat. The host sends it to the
server, which runs it only for a reader who may save that Plot’s SQL and
refuses anyone else with HTTP 403, PA-AU-019 and the reason before any query
starts (Plots). The host refuses it
in Labs and in the pictures Ponder takes of a Pane.
The frame cannot move the reader, but it can ask the host to. pages in the
Pane’s module moves between the Parable’s Pages:
The host answers
open and back only just after a click or key press in the
frame, only for a live Page of the mounted Parable (anything else is
HANDLE_UNDECLARED), at most once a second, and only on a surface that has an
address of its own. A Parable open in the app has one. Labs and the pictures
Ponder takes of a Pane have none, and the host refuses them there with
SCOPE_REFUSED. Call them from an event handler, never on mount. A Page is
composition only and cannot import the shared controls, so a designed control
that moves between Pages belongs in a Pane.
A press counts as in the frame only when three things hold: the frame has
focus, the browser reports a fresh click or key press, and the reader has
pressed nothing elsewhere in the app since the frame took focus. Typing in
Ponder’s composer, or clicking the app around the Page, is not a press in the
frame, so Pane code that calls on a timer is refused while the reader works
elsewhere. After a click outside the frame that leaves focus in it, the reader
clicks into the frame again before it may act.
One gap remains. Pane code that moves focus into its own frame, for example by
calling focus() on one of its inputs, passes this check while the reader’s
last press elsewhere is still fresh, about five seconds. The reader sees it:
their typing lands in the Pane instead of where they were typing.
The frame also reaches Ponder through the host (see
Ponder). ponder.path is
every reader’s; the rest need a reader who can use Ponder:
Each turn is an ordinary Ponder turn under the reader’s own permissions, with
Ponder’s tools; a tool call that changes something waits for the reader’s
approval in Ponder’s column. The host answers
compose, ask, path and
continue only just after a click or key press in the frame, as it does
pages.open, so Pane code cannot start a turn on mount, on a timer, or while
the reader types in Ponder, short of the focus gap above. It checks that the calling Pane is
one of the Page’s and that a named Plot is one it declares, and keeps one turn
running per Pane and one path per part it explains. Labs, unsaved previews, View as
and the pictures Ponder takes of a Pane get none of these.
Stopping a turn ends its reply in Ponder, not only on the page: the host calls
Ponder’s stop for the reply, so it runs no further, and the conversation
shows it stopped. A new ask from the same Pane stops the last one
the same way and waits for it to end before it sends, since Ponder runs one
turn at a time per conversation. A turn stopped before its reply has started is
stopped as soon as the reply starts. When a Pane’s remembered conversation no
longer exists, the next ask starts a new one; any other failure, such as a cut
off reply or a refusal, reaches the Pane and keeps the conversation.
A turn a Pane starts is the one exception to a Pane reading only its declared
Plots: it keeps the reader’s whole Workspace reach. The Pane names what the
reader pointed at, and Ponder’s tools then read anything the reader may read,
as they do in Ponder’s column. The Pane’s own Policies limit what its Plots
return, not what that turn reads.
Which Providers the Workspace has connected is Pane data: a Pane reads it
with a Plot over workspace.providers, and which of their streams are on over
workspace.provider_connections, and passes the rows to
ImproveParable and PopulateParable,
so anyone who can read the Parable sees connection health. A Provider or stream
that is missing reads as an empty table, so the Pane draws its empty state
rather than failing. Connecting one is
an action, which the frame asks the host for:
Labs, View as and the pictures Ponder takes of a Pane get no
providers.connect, and the components there offer no Connect. A reader who may not create a connection
reads “View only” on the setup page. It needs a click or key press in the
frame, as pages.open does. Setup never runs in the frame: a credential form there would
run in the author’s code, and OAuth needs a window the frame cannot open.
A row that stands for a record in a Provider, such as a pull request on
GitHub, can link to it. The frame cannot open a tab, so it asks the host:
openExternal comes from the Pane’s module, beside pages, and
ExternalLinkButton calls it
for a row. The host opens only an https URL. It refuses javascript:,
data:, file:, a relative address and a URL that carries a user name or
password with SCOPE_REFUSED, and plain http too. It opens a link only just after a
click or key press in the frame, as it does pages.open, so Pane code cannot
open one on mount or on a timer, and one press opens one tab: opening a tab
spends the press. It never moves the Parable page: the link opens in a new
tab or not at all, and a browser that blocks the tab does not tell the Pane.
Every surface the reader can press opens links, Labs and View as included.
A Pane can also start a run of the Parable’s Report. When a saved row that a
Pipeline read changes after the Refresh that made the Pane’s result started,
the Pane shows These settings changed since the last run, with Preview
and Run. The notice asks the host:
The host starts a Preview or a Refresh only just after a click or key press in
the frame, as it does
pages.open, so Pane code cannot start one on mount or
on a timer. Under View as, and on a Parable whose Pipelines are off, the host
starts neither, and refresh.available answers false. The server then checks
the person who pressed: a Preview or a Refresh starts only for a person who
holds Publishing or Primary on the Parable and the Workspace’s permission to
manage Parables.
The trust boundary is therefore the author, not the code. Pane code sees what
the reader it runs for is permitted to read through declared bindings and the
files module. After the reader presses something, it also sees what a Ponder
turn reads and streams back as that reader. The Workspace’s files are the one
exception. For them, the reader’s seat, the declaration in the Pane’s
Perception, and the permissions of the people who last saved the code decide
(Files in Pane code). A
sandboxed frame can still navigate itself, so
an author who wanted to could send those rows somewhere else, and a link a
Pane opens goes to whatever https address its author chose. Treat the
ability to author or propose a Pane like the ability to write its SQL: grant it
through Publishing permissions,
review proposals before accepting them, and use Policies to limit what a Pane’s
Plots return rather than expecting the renderer to hide anything from its own
author. Policies do not limit a Ponder turn the reader starts from a Pane;
the reader’s own permissions do.
A Pane’s code never acts with more rights than its author. Every proposal
(propose.change, propose.piece), every save of a row that a Policy
reads, and every save of a Default row is a privileged write. The host draws a confirmation outside the frame
that names the Pane, its author and the change. Only the reader’s click on it
lets the write go (PA-AU-069). Pane code cannot draw or click it. One kind of
proposal needs no click: see Changes that apply at once. A value
that comes from the Pane’s code, such as an item id or a new Piece’s name,
shows apart from the host’s words, in its own code element, cut to 40
characters with an ellipsis. The full value shows when you point at it. The
server then allows the write only when the reader holds the right and each
person whose code acts in the frame holds it too (PA-AU-070). The host asks only after every other check
passes: a reader who lacks a right the change needs, such as edit.policies
on a Page or Pane whose filter Policies read a Plot the change edits, is
refused first, and no set of Changes opens. These people are each person who last saved
the code of a Page or Pane that the frame draws, and each must be an active
member of the Workspace where they saved the code. Code that the platform saved counts for nobody, so a
frame with only platform code is refused. A Default row also needs each of them
to hold Primary. Each person is checked where they saved the code. On a copy, code that came with a Release is checked on
the Parable the copy comes from, with that line’s current members, seats and Policies, and code
saved on the copy is checked on the copy. This holds for an older Version of the copy too: each
row of code is checked on the line where it was saved, against that line’s current tree. So when
a later Release removes the Pane on the source, a write from that Pane’s code in an older Version
is always refused. This rule is the same for a copy of a Platform Parable: Parable staff wrote its
code, so their rights on the platform line cap it. The confirmation and the refusal name only
people of the reader’s own Workspace. Other people show as people from the Parable the copy
comes from. View as refuses every privileged write. A reader’s own rows save with no confirmation. So do team and This Parable rows that no
Policy reads.
Changes that apply at once
A Parable’s own Pane code may change its Pane data with no confirmation (PARABLE-9409). The change goes into the reader’s own Pending Patch and shows at once. The server decides this. It needs all of these:- The change is an edit of Pane data (
propose.changewithdata). A change to Policies or SQL, and a new Plot (propose.piece), still ask. - The Parable has Published Versions. On a Personal Parable a change is live at once, so it still asks.
- The reader holds Publishing or Primary.
- Each person who saved code that the frame draws saved it on this Parable. Code that came with a Release from the Parable a copy comes from still asks. The frame runs the Parable’s own code, or the code of the Patch that the change goes into. Code that a colleague saved in their own Patch still asks. Code that a colleague saved in the reader’s own Patch still asks too. A colleague with Publishing who sees a Problem that a person started can save code into its Patch. So the reader must have saved each Page and Pane code in the Patch that differs from the Parable’s own code.
- The reader may view the changed Pane’s data, so the banner can list each item.
- The change goes into a Patch that the reader started and that is still Pending. With no Patch named, the server picks the reader’s newest Pending Patch or opens one in a new Problem, Changes from the Pane’s name. A colleague’s Patch still asks.
PA-AU-070) apply as
for a confirmed change. View as refuses the change. With no Problem open, the
host first asks the server whether the change would apply at once. Nothing is
written yet. When it would, the host starts the Problem where the Start
Changes rule puts it and sends the change into it, with no dialog.
While a person reads a Pending or Proposed Patch, the host draws the
Unpublished Changes banner above the Page, outside the frame. It counts
what the Patch holds that readers do not see yet. It lists each Pane data item
that differs from the Release, with Undo, and each other change, with
Open. Undo puts the item back to its value in the Release. The banner
offers the next step of the Publishing flow: Propose Changes while the
Patch is Pending, then Publish or Keep Editing once it is Proposed.
A change reaches readers only when a person Publishes the Patch.
A Ponder turn that a Pane starts (ponder.ask) runs with the rights of the
reader who clicked. The author’s cap does not apply to that turn, because the
reader’s click is the reader’s own act.
Files in Pane code
Pane code reads the Parable’s files, and adds a file to it, withfiles from
the Pane’s module. A Lab imports the same files from parable. The host
answers for the Parable on screen, so Pane code never names a Parable.
files.list and files.upload give each file as a PaneFile:
This Pane lists the Parable’s data files with their table addresses, and adds
a data file when the reader presses its button:
files.read refuses a file larger than 25 MB (25,000,000 bytes) with
FILE_TOO_LARGE and “This file is larger than 25 MB. Read its rows through a
Plot.” The host checks the bytes too, and stops reading at the limit. A Page
has at most two files.read calls in flight. A third gets RATE_LIMITED
until one of them is done. The rows of a data
file belong in a Plot that reads its table
(Plots). Use
files.read for small files, such as a JSON settings file or a short CSV.
files.read answers ARTIFACT_NOT_FOUND and “This file is not available.”
for a file that the Parable or the Workspace does not hold. It answers the same
for a deleted file and for a file whose check has not ended. The host fetches the bytes, so the frame never gets a storage
address.
The host opens the picker only just after a click or a key press in the
frame, as it does pages.open. The file goes into the Parable’s files through
the same upload and check as in the Artifacts tree. Only a person with Primary
or Publishing adds a file, and only in the Publishing mode. The browser may
not let the host open the picker from the press. Then the host shows a dialog,
Add a file to this Parable, whose Choose a file button opens the
picker. The call waits up to five minutes for the check, counted from the
call, with the time in the picker. After that it fails with TIMEOUT, and the
file shows in the Artifacts tree when its check ends.
The host refuses an upload in these cases:
The server checks the upload as it checks an upload from the Artifacts tree.
Its refusal, such as for a name or a size, comes back as
FILE_REFUSED with
the server’s reason.
ArtifactImage, ArtifactVideo and Palette fonts need no files call. The
pictures Ponder takes of a Pane read no files. Every files call there gets
SCOPE_REFUSED and “This surface reads no files.”
The Workspace’s files
The Workspace’s files reach Pane code under rules of their own. The reader needs only a seat on the Parable: Primary, Publishing, Pinging or Peeking. The reader needs no Workspace permission for files. Three rules apply:- The Pane declares that its code reads the Workspace’s files. Its
Perception holds
readonly workspaceFiles: true;. A Pane’s code asks for its own Pane. A Page’s code asks for the Page, so the Page’s Perception holds the declaration. - Only a person whose Workspace role lists the Workspace’s files saves a Perception that declares it: the role holds the permission to view Artifacts or to upload them. The rule applies to each save that changes a Perception and keeps the declaration in it: an edit in the Parable editor, an edit from Ponder, a change from Pane code, and an archive import. A save that keeps the stored Perception, or that removes the declaration, needs no such permission.
- Every person who last saved code that runs in the Page’s frame holds the Workspace’s permission to view Artifacts or to upload them. The code in the frame is the code of the Page and of each Pane that it renders. On a copy, code that was saved on the Parable the copy comes from never reads the copy Workspace’s files. When any code in the frame comes from there, the server refuses.
Pane code gets the second and third refusals from
files.list({ from: 'workspace' })
and from files.read of a Workspace file, with the code and the message. So
Pane code reaches no further than the people who saved it.
A copy that takes a Release by Pull or by Delivery gets the declaration with
the Release. That is not a person’s save, so rule 2 does not apply to it.
Rule 3 still applies on the copy.
What the declaration does not limit. The server cannot tell which code
asks for the files. Through a Pane that declares workspaceFiles, a reader
can list and read every checked Workspace file that holds no Provider’s data,
not only the files that the Pane shows. Declare it only on a Parable whose readers may see all of the
Workspace’s checked files.
Pane-started runs
In a composed Parable, a Pane can start one Preview every 10 seconds and one Run every minute for each reader and Deployment. All Panes on that Deployment share these limits. A Preview does not use the Run allowance. Across several tabs, the limit counts in fixed 10-second and one-minute periods, so two tabs can start two runs a moment apart across a period boundary. When a Pane asks too often, it shows one of these refusals and starts no extra run:- Preview.
This Pane asked to preview too often. Try again in 10 seconds. - Run.
This Pane asked to run too often. Try again in a minute.