cupertino-files / ObjectStore
Class: ObjectStore
Defined in: src/tsp/store.ts:134
Constructors
Constructor
new ObjectStore(
container,options?):ObjectStore
Defined in: src/tsp/store.ts:156
Parameters
container
options?
app?
containerParentOf?
ContainerParentResolver
referenceExtractors?
ReadonlyMap<number, ReferenceExtractor>
Returns
ObjectStore
Properties
app
readonlyapp:IWorkApp
Defined in: src/tsp/store.ts:137
components
readonlycomponents:Component[] =[]
Defined in: src/tsp/store.ts:136
container
readonlycontainer:IWorkContainer
Defined in: src/tsp/store.ts:135
pendingFiles
readonlypendingFiles:Map<string,Uint8Array<ArrayBufferLike>>
Defined in: src/tsp/store.ts:328
Files to add to the package on save (e.g. "Data/photo.png").
Accessors
packageMetadata
Get Signature
get packageMetadata():
IwaObject
Defined in: src/tsp/store.ts:214
Returns
Methods
addDataFile()
addDataFile(
data,preferredFileName):object
Defined in: src/tsp/store.ts:336
Register media bytes as a Data/ file: dedupes by SHA-1 digest against existing DataInfos, allocates a data-space identifier, appends the DataInfo to PackageMetadata and schedules the file for writing. Returns the data identifier and stored file name.
Parameters
data
Uint8Array
preferredFileName
string
Returns
object
dataId
dataId:
bigint
fileName
fileName:
string
allObjects()
allObjects():
IterableIterator<{component:Component;obj:IwaObject; }>
Defined in: src/tsp/store.ts:208
Returns
IterableIterator<{ component: Component; obj: IwaObject; }>
allocateId()
allocateId():
bigint
Defined in: src/tsp/store.ts:228
Allocate a fresh object identifier. First allocation rounds the current maximum up to the next multiple of 1,000,000 (numbers-parser convention, keeping new IDs clear of Apple's); every allocation is recorded in PackageMetadata.last_object_identifier.
Returns
bigint
componentByLocator()
componentByLocator(
locator):Component|undefined
Defined in: src/tsp/store.ts:185
Parameters
locator
string
Returns
Component | undefined
componentInfo()
componentInfo(
component):RawMessage|undefined
Defined in: src/tsp/store.ts:380
ComponentInfo message inside PackageMetadata for a component, if any.
Parameters
component
Returns
RawMessage | undefined
componentOf()
componentOf(
id):Component|undefined
Defined in: src/tsp/store.ts:181
Parameters
id
bigint
Returns
Component | undefined
createComponent()
createComponent(
locator,modeledOn):Component|undefined
Defined in: src/tsp/store.ts:472
Create an empty component and register it in the package metadata.
Measured from a Keynote-saved multi-slide deck (olekristensen-v26.3-mac-builds-effects.key): each slide lives in a component of its own whose ComponentInfo carries the slide's id as identifier, the bare kind as preferred locator ("Slide"), the full Slide-<id> as locator, the document read/write versions, an explicit is_stored_outside_object_archive: false, the save token, and the external references its content needs. modeledOn supplies everything content-dependent: versions and save token are copied from its info, and its external-reference rows are mirrored verbatim — right for a component whose objects reference the same styles and master as the donor's, which is what a slide copy does. The apps' own slide infos also carry per-object UUID map entries; a component created here has none, a difference Keynote accepted in every measured save.
Returns undefined when the package keeps no metadata (nothing to register against) or the locator lacks the Kind-<digits> shape.
Parameters
locator
string
modeledOn
Returns
Component | undefined
createObject()
createObject(
type,component,options?):IwaObject
Defined in: src/tsp/store.ts:248
Create a new object of the given type inside a component. The MessageInfo version list is copied from an existing sibling of the same type when one exists (falling back to [1, 0, 5], which is what numbers-parser writes). cloneFrom seeds the payload with a copy of another object's message.
Parameters
type
number
component
options?
cloneFrom?
Returns
currentReferencesOf()
currentReferencesOf(
obj):bigint[]
Defined in: src/tsp/store.ts:628
The references an object holds right now, computed from its message rather than read from the declarations, which refresh only at save.
The clone walk needs this: selecting from stale declarations made a copy of a just-inserted drawable share every owned child the original had — its title and caption stand-ins, and its mask had it been cropped — because none of them was declared yet. For an Apple-written object with no extractor the declarations are the truth, exactly as at save.
Parameters
obj
Returns
bigint[]
dataFileName()
dataFileName(
dataId):string|undefined
Defined in: src/tsp/store.ts:521
File name registered for a Data/ identifier, from PackageMetadata.datas.
Parameters
dataId
bigint
Returns
string | undefined
declareComponentDependency()
declareComponentDependency(
fromComponent,toComponentId):void
Defined in: src/tsp/store.ts:435
Ensure fromComponent's ComponentInfo carries a component-level external reference (no object identifier) to the component whose ComponentInfo identifier is toComponentId — the shape the apps use for whole-component dependencies, such as the document's row for each slide component.
Parameters
fromComponent
toComponentId
bigint
Returns
void
declareReference()
declareReference(
referrer,id):void
Defined in: src/tsp/store.ts:606
Declare that referrer now points at id, adding the cross-component bookkeeping if the two live apart.
retargetReference covers "this reference moved"; this covers "there is one more of them", which is what adding an entry to a list inside an existing archive needs. Both matter for the same reason: an undeclared reference into another component is how an app decides a document is damaged.
Parameters
referrer
id
bigint
Returns
void
findByType()
findByType(
type):IwaObject|undefined
Defined in: src/tsp/store.ts:201
Parameters
type
number
Returns
IwaObject | undefined
isCreated()
isCreated(
id):boolean
Defined in: src/tsp/store.ts:152
True for an object this library created rather than read.
Parameters
id
bigint
Returns
boolean
moveObjectsToComponent()
moveObjectsToComponent(
ids,component):void
Defined in: src/tsp/store.ts:504
Move objects into component, keeping index and dirtiness straight. The objects' identities and payloads are untouched; only which IWA file they serialize into changes.
Parameters
ids
Iterable<bigint>
component
Returns
void
object()
object(
id):IwaObject|undefined
Defined in: src/tsp/store.ts:177
Parameters
id
bigint
Returns
IwaObject | undefined
prune()
prune(
roots):number
Defined in: src/tsp/store.ts:288
Drop objects nothing can reach, and report how many went.
Deleting a sheet or a slide unlinks its archives but does not remove them: they sit in their component, unreferenced, and go on being written out. A document blanked from a real one is mostly this — a template with eleven tables becomes one table and ten ghosts.
Why the scan is deliberately crude
Reachability is computed by walking every submessage of every object and treating anything shaped like a TSP.Reference — a message whose only field is varint 1 — as a pointer, if that value names an object. No schema is consulted.
That over-approximates: a field that happens to hold an integer equal to some object's id keeps that object alive for no reason. This is the safe direction. The alternative, walking only the references this library knows how to extract, would silently drop whatever an unmodelled archive points at — and a document that loses an object it needed is unrecoverable, while one that keeps a few too many is merely larger than it could be.
Objects in components that failed to decode are never touched, and neither are the roots.
Parameters
roots
readonly bigint[]
Returns
number
referrers()
referrers(
id):bigint[]
Defined in: src/tsp/store.ts:560
Objects declaring a reference to id, per MessageInfo.object_references.
The cheap, accurate way to ask "is this archive shared?" — Apple keeps the declarations current, so a style used by ten charts is named by ten objects. Answering by scanning payloads instead would mean parsing every archive in the document.
Only as good as the declarations: an object whose references this library has not recomputed reports what it reported when Apple wrote it. For deciding whether to copy-on-write, that errs toward copying, which is the safe direction.
Parameters
id
bigint
Returns
bigint[]
resolve()
resolve(
ref):IwaObject|undefined
Defined in: src/tsp/store.ts:190
Resolve a TSP.Reference message (field 1 = identifier) to its object.
Parameters
ref
bigint | RawMessage | undefined
Returns
IwaObject | undefined
retargetReference()
retargetReference(
referrer,oldId,newId):void
Defined in: src/tsp/store.ts:585
Note that referrer now points at newId where it pointed at oldId.
Used after copy-on-write: the payload has been repointed, and the bookkeeping has to follow. Doing it here rather than through a ReferenceExtractor is deliberate — an extractor replaces the whole declared list, so writing one for a type as broad as TSCH.ChartDrawableArchive would silently drop every reference it failed to enumerate. This changes exactly the one that moved.
oldId is dropped only when the payload no longer mentions it: one archive can be pointed at from several slots, and a shared style being privatised for series 2 may still be in use by series 4. The membership test over-approximates, so the failure mode is keeping a declaration a little too long — harmless, since the object still exists — rather than dropping a live one.
Parameters
referrer
oldId
bigint
newId
bigint
Returns
void
save()
save():
Uint8Array
Defined in: src/tsp/store.ts:663
Serialize the document. Recomputes reference bookkeeping for dirty objects, then rebuilds only the components that changed.
Returns
Uint8Array
staleCompatibilityPatches()
staleCompatibilityPatches():
object[]
Defined in: src/tsp/store.ts:537
Objects edited in this session that carry older-reader compatibility diffs (see IwaObject.compatibilityPatchVersions). The diffs are preserved verbatim but NOT recomputed, so an older app opening the saved document would apply a stale diff for those objects. Empty in practice unless you edit UI-state objects.
Returns
object[]
typeNameOf()
typeNameOf(
object):string|undefined
Defined in: src/tsp/store.ts:197
Registry name of an object's archive type, resolved for this app.
Parameters
object
Returns
string | undefined