Skip to content

Release Next v3.0.0-next.23

Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 06 Nov 16:44
· 151 commits to main since this release
3f7f3c6

@cloudpdf/contract@3.0.0-next.23

Minor Changes

  • #991 by @bobsingor – The manifest and a mutation's cacheDelta have contentsVersion, the document-wide pin of every page's content.

  • #989 by @bobsingor – GET …/head answers engine, the server's engine value for each kind of cached read. The manifest no longer has serverFonts.

  • #994 by @bobsingor – Every error response is the one error body, ErrorResponse, with its error EngineError; AdminErrorPayloadSchema and AdminThumbnailUnavailablePayloadSchema are gone, and a thumbnail that isn't ready says its state in details.state. Operations no longer get a type per error status, so a response type is named after its operation alone (DocFormsListResponse, not DocFormsList200Response). Sizes, counts, durations and the admin timestamps are integers. nextCursor, thumbnailState and thumbnailUrl are always there, and the license status's license, reporting and usage too (null when there's nothing). A union of whole-number literals, such as a rotation or a DocMDP level, is one integer enum in openapi.json.

  • #996 by @bobsingor – Every point in time is an ISO 8601 string (format: date-time): createdAt, updatedAt, archivedAt, lastExchangedAt, firstSeenAt, lastSeenAt and consentedAt on tenants, documents, folders, grants, layers and visitors, and every expiresAt (grants, the upload URL, tokens, grant sessions, download links), which were milliseconds in some places and seconds in others. A request gives one with its offset: a grant's expiresAt, and a token revoke's expiresAt, which replaces expiresAtSeconds. A date a write takes as a Date in process is a date-time string in openapi.json. A schema a model reuses no longer takes the nullable of the field that used it first: a grant's createdAt and updatedAt, and a visitor's firstSeenAt and lastSeenAt, read as non-null.

  • #997 by @bobsingor – Names and units follow one rule: a document's baseSha and storageSizeBytes are baseSha256 and sizeBytes, and so is a layer's and a visitor's layer's storageSizeBytes; the init request's contentLength and uploadTtlSec are sizeBytes and uploadTtlSeconds; token issue's and the download link's expiresIn is expiresInSeconds; folders move-into takes docIds (its 404 names details.docIds); usage metrics are pdfViews, pdfUploads and storageBytes, and a module's meters move to their own moduleMeters map; and the path parameters are {docId}, {annotationKey}, {sha256} and {displaySha256} (the URLs don't change).

  • #995 by @bobsingor – A destination's axes are always there, null to keep the viewer's value, and a document's openDestination is always there. A line's captionEnabled is a boolean, never null. A grant create takes null for origins and expiresAt, as a grant read says them, meaning any origin and no expiry.

  • #1005 by @bobsingor – A document head's permissions.flags (the named PdfPermissionFlags) replaces the raw bits word.

  • #982 by @bobsingor – A widget reads hasMark: true when it is a signature field's widget with a
    mark in it, because the field is signed or a mark was drawn in. Such a widget
    shows the mark, and a change to its style is refused.

  • #1002 by @bobsingor – The document init and import answers say what happened in status (created, resumed or deduped; imported, deduped or accepted), not tag, as every call's answer does. Form fields are tagged kind (was family) and a widget says fieldKind. The contract test checks that a union is tagged type, kind, status or subtype.

  • #992 by @bobsingor – The contract declares EmbedPDF-Version as a literal global header, so every generated SDK sends the major and minor of the release it was generated from.

Patch Changes

  • #993 by @bobsingor – openapi.json writes a field's stored value and a measure out once, as FormValueEntry and PdfMeasurement, instead of once per field family and annotation kind, and each union and enum with a catch-all says what an unknown kind or value reads as. A new test fails when a union with a catch-all has no name in the contract, no row in the SDK checks' list or no fixture case. SHARED_COMPONENT_SCHEMAS is exported from @cloudpdf/contract/openapi.

  • #990 by @bobsingor – Every response schema reads tolerantly: none refuses a field it doesn't know, and every set it carries is marked closed or names what an unknown value reads as, which a new test checks for each operation. A request naming an identity is still parsed strictly, and the OpenAPI projection maps that strict twin to the same Identity component, so openapi.json is unchanged.

@cloudpdf/engine@3.0.0-next.23

Minor Changes

  • #991 by @bobsingor – Searches pin the manifest's contentsVersion and layoutVersion, copied rather than computed, and a write's contentsVersion is absorbed into the cached manifest.

  • #989 by @bobsingor – Cached reads copy each kind's engine value from /head into their URLs, with the shape this client reads. An answer that names another engine value (EmbedPDF-Engine) makes the next cached read learn /head again.

  • #994 by @bobsingor – Every server error reads as an EngineError with the server's code: GrantExpired, OriginNotAllowed, OriginRequired, EngineBusy and the rest of the codes the server sends are the error's code, not Forbidden or Unknown. A code this client doesn't know falls back to the HTTP status.

  • #996 by @bobsingor – A grant session's expiresAt is an ISO 8601 string, and renewal works from it.

  • #992 by @bobsingor – Every request to the server says which version the client speaks, in EmbedPDF-Version. A read through a CDN leaves it out: its answer never depends on it.

Patch Changes

  • #997 by @bobsingor – Reads the renamed engine fields (displaySha256, contentsSizeBytes, baseSha256, and the editing session's expiresInSeconds).

  • #995 by @bobsingor – GrantSessionOptions.visitorStore is a VisitorStore, left out for none.

  • #1005 by @bobsingor – Reads the head's named permission flags; follows engine-core's names.

  • #998 by @bobsingor – A document opened with a token that may not read another client's write, its annotations or its form fields, now hears fonts.changed when that write changed the document's fonts, as one that may read the write does.

  • #1003 by @bobsingor – Follows engine-core's names; exported functions take options.

  • #1000 by @bobsingor – Follows engine-core: an event's origin says subject, at (ISO 8601), serverSequence and transaction; the grant's callbacks are onIdentityRequested and onOpenRequested, and its resume() takes visitorIdentity.

@cloudpdf/sdk@3.0.0-next.23

Minor Changes

  • #991 by @bobsingor – The manifest and cache delta types have contentsVersion.

  • #989 by @bobsingor – The head type has engine, the server's engine value for each kind of cached read; the manifest type no longer has serverFonts.

  • #994 by @bobsingor – Every error response is one type, ErrorResponse, with its error EngineError and a code from one list, replacing EngineErrorPayload, AdminErrorPayload and the per-operation error types such as DocHead404Response. A response type is named after its operation alone (DocFormsListResponse, not DocFormsList200Response). Sizes, counts, durations and timestamps are integers, and nextCursor, thumbnailState and thumbnailUrl are always there. A signature's fieldMdp and lock are FieldLockSpec, whose permission is a DocMdpPermission that is never null. A DocMDP level and a page or widget rotation are integers.

  • #996 by @bobsingor – Every point in time is an ISO 8601 date-time string, where createdAt, updatedAt, the other …At fields and every expiresAt were numbers in milliseconds or seconds. A token revoke takes expiresAt instead of expiresAtSeconds. A grant's createdAt and updatedAt, and a visitor's firstSeenAt and lastSeenAt, are no longer typed nullable.

  • #997 by @bobsingor – Names follow one rule: sizeBytes (documents, layers, versions and the init request), baseSha256, a manifest's baseSizeBytes, uploadTtlSeconds (also on uploads.create), expiresInSeconds, docIds, md5, displaySha256 and sourceSha256, contentsSizeBytes, changedRefs, usage metrics pdfViews, pdfUploads and storageBytes with module meters in a typed moduleMeters map, a submit-form action's named flags, a seed value's …Required booleans and parserVersion, and the path arguments docId, annotationKey, sha256 and displaySha256. /access, the event stream's session event and object-number reservations say expiresInSeconds. Action trees drop warningFlags.

  • #995 by @bobsingor – A destination's x, y and zoom are always there, null to keep the viewer's value, and a document's openDestination is always there. A line's captionEnabled is a boolean, never null. A grant create takes null for origins and expiresAt, as a grant read says them.

  • #993 by @bobsingor – A field's stored value and a measure are one type each, FormValueEntry and PdfMeasurement, replacing the per-family and per-kind copies such as FormFieldTextValueEntry and AnnotationLineMeasure. The documentation of each union and enum with a catch-all says what a kind or value the SDK doesn't know reads as.

  • #1005 by @bobsingor – A document head's permissions.flags (PdfPermissionFlags) replaces bits.

  • #982 by @bobsingor – WidgetAnnotation has hasMark: true for a signature field's widget with a
    mark in it (signed, or a mark drawn in), whose style can then no longer change.

  • #1002 by @bobsingor – uploads.create() and upload() resolve { status, document } (was tag). Form fields are tagged kind, and the init and import answers say status.

  • #992 by @bobsingor – Every request sends EmbedPDF-Version, the version the SDK was generated from.

@cloudpdf/server@3.0.0-next.23

Minor Changes

  • #991 by @bobsingor – Layers and base versions store contents_version (migration 052), raised in the same transaction as a flatten, a redaction or a change to the page set, and published in the manifest. Versioned searches pin it with layoutVersion instead of a content epoch, so an annotation write keeps every cached search and a content write refreshes them; the unversioned search form takes the same two pins as optional parameters.

  • #989 by @bobsingor – /head carries this server's engine value for each kind of cached read: a digest of the rules and fonts it computes that kind with, never of its release, so a deploy that changes nothing keeps every cached answer. Every versioned read checks the token's engine value and shape: a shape newer than the server answers is refused, and another engine value is answered with this server's own answer, uncached, and its value in EmbedPDF-Engine (exposed to browsers), so nothing is cached under a value that doesn't describe it and no request fails during a rolling deploy. Renders are stored by engine value. The manifest no longer carries serverFonts.

  • #994 by @bobsingor – Every error response is { error: { code, message, details? } } with a code from EngineErrorCode. An engine error no longer carries name. A license refusal is LicenseInvalid with the license status's code in details.licenseCode; a usage limit says its metric and limit in details; a thumbnail that isn't ready says its state in details.state; BadInput is InvalidArg; and an error from Fastify itself carries the code for its status instead of Fastify's own.

  • #996 by @bobsingor – Every point in time the server sends is an ISO 8601 string in UTC, and a grant's and a token revoke's expiresAt are taken as one, with its offset. Rows keep their milliseconds. The admin routes' records are typed by the contract's, so a field the contract doesn't say no longer compiles.

  • #997 by @bobsingor – Takes and sends the renamed fields: sizeBytes (documents, layers, versions), baseSha256, the manifest's baseSizeBytes, uploadTtlSeconds, expiresInSeconds (also the editing session's on /access, the event stream and object-number reservations), docIds and the camelCase usage metrics (module meters in moduleMeters), and names its path parameters docId, annotationKey, sha256 and displaySha256.

  • #992 by @bobsingor – Every response says which version the server is, in EmbedPDF-Server-Version. A request's EmbedPDF-Version is answered within the server's major; another major, or a value that isn't <major>.<minor>, gets a 400 naming both versions. CORS allows EmbedPDF-Version and exposes EmbedPDF-Server-Version.

Patch Changes

  • #995 by @bobsingor – A grant create takes origins: null and expiresAt: null, as a grant read says them: any origin and no expiry.

  • #1005 by @bobsingor – The head and /access carry named permission flags, not the raw word; /access no longer sends the advisory.

  • #988 by @bobsingor – Every versioned read (…@token) now answers exactly the state its pins name. The pins are checked before the read and again after it, and a read that a layer write began during is refused as no longer current, so a write can no longer end up cached for a year under an older version. Before, page renders, page text and geometry, appearance batches, outline, metadata, fonts, attachments, layout, actions, search, signatures and downloads checked their pins only before reading, and the annotation and form reads could still send an applied but uncommitted write.

  • #990 by @bobsingor – redactions.apply parses its body with RedactionApplyScopeInputSchema, which still refuses a field it doesn't know, now that the scope a response carries is read tolerantly.

  • #1003 by @bobsingor – Follows engine-core's names: FormField, Signature.

  • #1002 by @bobsingor – The document init and import answers say status, not tag. Form fields are tagged kind.

  • #1000 by @bobsingor – The image encoder and the appearance batch say mimeType, as engine-core's render results do.

@embedpdf/core-acrojs@3.0.0-next.23

Minor Changes

  • #999 by @bobsingor – cssToScriptColor(css) takes string | null; null is transparent.

  • #1003 by @bobsingor – A script's page move is the effect { type: 'goToPage', pageIndex } (was gotoPage with page).

  • #1002 by @bobsingor – A script's field input says kind (was family), as engine-core's form fields do.

  • #1000 by @bobsingor – ScriptUiEffect is tagged type, as effects are things that happen (was kind). The script host ends with destroy() and says destroyed.

@embedpdf/core-annotation@3.0.0-next.23

Minor Changes

  • #999 by @bobsingor – writableTarget(target) takes PdfLinkTarget | null, no undefined.

  • #982 by @bobsingor – A signature field's widget with a mark in it is the widget-mark kind, which has no style rows, so a style panel offers nothing that wouldn't show. widgetKindOf takes the widget (its fieldFamily and hasMark), and drawsLive is exported.

  • #1003 by @bobsingor – Geometry names are spelled out: anchoredGeometry, unanchoredGeometry, effectiveGeometry, obbFromGeometry, isRotatableGeometry.

  • #1002 by @bobsingor – fieldKindOf() replaces fieldFamilyOfKind(), and a widget's fieldKind replaces fieldFamily.

  • #1000 by @bobsingor – The snap settings name their units: alignmentThresholdPx and rotationThresholdDeg.

Patch Changes

  • #995 by @bobsingor – The editor's rich text predicts the engine's rule: a body it gives is replaced whole over the defaults, and without one the annotation's body is kept.

  • #985 by @bobsingor – The rich text model's plain projection joins paragraphs with \n, and a hard line break inside a run is \n, matching the rich text the engine returns.

@embedpdf/core-form@3.0.0-next.23

Minor Changes

  • #999 by @bobsingor – widgetScene(drawing, placement) takes a WidgetScenePlacement (was WidgetPlacement, the engine's name for a widget draft's placement).

  • #982 by @bobsingor – The painter draws a signature field's widget: its box, the background and border as a text field draws them, exactly as the engine writes it.

Patch Changes

@embedpdf/core-geometry@3.0.0-next.23

Minor Changes

  • #1003 by @bobsingor – Rotation replaces PageRotation, beside Rect, Point and Size.

@embedpdf/core-js-sandbox@3.0.0-next.23

Minor Changes

  • #1000 by @bobsingor – The QuickJS sandbox ends with destroy() and says destroyed, as every other object does.

@embedpdf/core@3.0.0-next.23

Minor Changes

  • #999 by @bobsingor – A settings declaration's whole names a setting inside a group by its path ('snapshot.box'), and a whole setting's change takes its defaults for what it leaves out, never the value before. mergeSettings(settings, changes, declaration?) takes the declaration (defaults and whole) instead of the whole list. MirrorSpec.load() answers cursor?: number, no null.

  • #1003 by @bobsingor – PluginDefinition<State, Capability, PluginSettings> replaces PluginDef<S, C, T>, and the generics of PluginContext<State, PluginSettings> and StateCell<State> are named.

  • #1000 by @bobsingor – destroy() is the one verb that ends an object's life, never dispose(): prepared and staged prints, Scope (with destroyed), event hook sources, the settings store and the test kernel. acquire(get, release) names its second argument for what it does. Kernel.getStatus() replaces status(). A document's page-list counter is pagesSequence (on DocumentMeta and DocumentPagesChangedEvent), not revision, which in a PDF means a saved file revision. PendingPage is tagged kind. Settings events carry changedKeys, as metadata's do. Mirror specs take onChanged. A document's grant question is openRequest, as the engine names it, and retry() takes visitorIdentity. changes.listPending() and the page view's getPending(page) start with a verb.

@embedpdf/core-signature@3.0.0-next.23

Minor Changes

  • #999 by @bobsingor – validateChain(cms, trust, at?) takes trust: TrustPort | null, no undefined.

  • #1000 by @bobsingor – SignatureVerdict.validationTime replaces validatedAt, which wasn't a time, and validateSignatures() takes validationTime (was at). Times are ISO 8601 strings: ParsedCms.signingTime, BuildDetachedCmsInput.signingTime and a timestamp ValidationTime's genTime.

Patch Changes

@embedpdf/core-stage@3.0.0-next.23

Minor Changes

  • #1003 by @bobsingor – PageGeometry replaces PageGeom, and an Anchor says fractionX and fractionY (were fx and fy).

@embedpdf/core-text@3.0.0-next.23

Minor Changes

  • #999 by @bobsingor – defaultPaintFonts(fontFamily) takes string | null, no undefined.

@embedpdf/core-ui@3.0.0-next.23

Minor Changes

  • #999 by @bobsingor – resolveLayout(option, defaults, env) takes option: LayoutOption | undefined, no null.

  • #1003 by @bobsingor – CustomSlotContext replaces CustomSlotCtx.

  • #1000 by @bobsingor – OverflowRow is tagged kind, as things that are are.

@embedpdf/engine-core@3.0.0-next.23

Minor Changes

  • #991 by @bobsingor – The manifest has contentsVersion, the document-wide pin of every page's content: it moves with any write that moves a page's contentVersion, inserts a page or deletes one, and a write's cacheDelta carries it when it moved. A search token pins contentsVersion and layoutVersion instead of epoch, and searchContentEpoch is gone.

  • #989 by @bobsingor – Every cached read's token carries its kind's engine value and the shape the client reads (engine, shape): the encoders take a TokenPin and the decoders return one as pin. CACHED_READ_KINDS, SHAPES, tokenPinOf, EngineValues and TokenPin are exported from the wire entry. DocumentHead gains engine, this server's engine value for each kind. DocumentManifest no longer carries serverFonts, and render and appearance tokens carry the engine value in its place. The layout and search tokens drop format (LAYOUT_FORMAT and SEARCH_RESULT_FORMAT are gone): their shape is shape. PAGE_TEXT_VERSION and LINE_BREAKS_VERSION version the rules page text and returned text are read by.

  • #994 by @bobsingor – One error body for every HTTP error, ErrorResponseSchema ({ error: { code, message, details? } }), and EngineErrorSchema for the error inside it, replacing EngineErrorPayloadSchema. A serialized EngineError no longer carries name. EngineErrorCode is the one code list: it gains the codes the server sends (Conflict, EngineBusy, EngineRestarting, DocumentQuarantined, ThumbnailNotReady, TooManyRequests, GrantExpired, OriginRequired, OriginNotAllowed, FeatureNotEnabled, FeatureStopped, LicenseInvalid, LicenseUsageLimit, UpstreamError), and isEngineErrorCode tells whether a value is one. SignatureWireComponents names DocMdpPermission and FieldLockSpec for the OpenAPI document.

  • #996 by @bobsingor – Every point in time on the wire is an ISO 8601 string: an access's expiresAt and its CDN's cdn.expiresAt (DocumentAccessInfo, CdnAccessInfo, AccessResponseSchema), a layer version's createdAt, and a prepared signature's expiresAt (now typed IsoDateTimeSchema). They were Unix seconds, and a layer version's milliseconds.

  • #997 by @bobsingor – Names, units and flags follow one rule (naming.md, "The HTTP API"):

    • Flags are named booleans. A submit-form action reads and writes exclude, includeNoValueFields, format, method and the rest flat on its payload or action, without a flags object or a raw word; encodeSubmitFormFlags is the inverse of decodeSubmitFormFlags. An action tree drops warningFlags (its warnings name them). A seed value says filterRequired, subFiltersRequired, parserVersionRequired, digestMethodsRequired and reasonsRequired instead of requiredFlags and presentFlags, and its version is parserVersion. A form submission's intent drops flagsRaw.
    • One name, one meaning. Mutation results list what they touched in changedRefs (was changed).
    • Units and algorithms in names. An attachment's size and checksum are sizeBytes and md5; a font program's displayHash and sourceHash are displaySha256 and sourceSha256; a version's byteLength is sizeBytes; a signature's contentsSize (and prepare's) is contentsSizeBytes; the head, the manifest and the version list say baseSha256, the head sizeBytes and the manifest baseSizeBytes (was baseByteLength); an editing session's expiresIn (EditSessionAccess, EditSessionStatus, an object-number reservation) is expiresInSeconds.
    • Path parameters are spelled out in wireTemplates: :annotationKey, :sha256 and :displaySha256. The document.fonts.program worker request names its program by displaySha256, and signatures.finalizeCandidate takes contentsSizeBytes.
  • #995 by @bobsingor – One spelling for "nothing" (naming.md, "Nothing: left out or null"):

    • A destination always has its axes: PageDestination's x, y and zoom (and PdfDestination's left, top and zoom) are always there, null to keep the viewer's value, never left out.
    • DocumentActionsSnapshot.openDestination is always there, null when the document has none.
    • CommentThreadReview.mine is always there: null when the reviewer has none, or when no currentUserId was given.
    • An annotation create's groupId: null is no group, refused to a caller who has one; left out is still the caller's own group. It used to put the annotation in the caller's group.
    • A free text's new rich text replaces the body whole when it gives one (what it leaves out takes the default, as on a comment), and keeps the current body when it doesn't. A partial body used to merge over the current one.
    • An annotation create left without nm still gets a fresh name; nm: null now writes none, as a file from a tool that names nothing reads. It used to mint one too. A copy leaves nm out.
    • A widget's fontFamily, fontSize and fontColor take values only: a font can't be removed, so null is only the read sent back (no font on the widget or the form), and is refused beside a font. It used to write Helvetica 12 black.
    • A line's captionEnabled reads false without /Cap, the PDF's default, and takes no null. A polygon's and polyline's keep null for no caption and no placement.
    • OpenOptions.password is string, left out for none.
    • LineCaptionPatch and ShapeCaptionPatch, unused, are gone.
  • #993 by @bobsingor – Every union a response carries with a catch-all kind is a named contract model: a field's stored value (FormValueEntry) and a measure (PdfMeasurement) join Annotation, FormField, PdfLinkTarget and PdfActionNode in the wire components. Each of the six, a widget's fieldFamily and an error's code now describe what a client reads a kind or value it doesn't know as. openUnionOf() and openUnionsIn() in @embedpdf/engine-core/conformance find the unions with a catch-all in a schema.

  • #985 by @bobsingor – Page text ends its lines in \n and leaves out the characters a reader can't see as text. A line break PDFium extracts as \r\n gives \n: its \r keeps its place in character space and gives no text. A Unicode noncharacter gives no text either, so a word PDFium joined across a line-end hyphen (which it marks with U+FFFE) reads, copies and searches whole: Verita- and serum read Veritaserum. Character positions don't change, so selections, highlights and search hits are where they were. New exports: toPageText (the projection), isNoncharacter and toLineBreaks.

    Search ignores invisible characters, so a match runs across a soft hyphen, a zero-width space or joiner, a bidi mark, U+FEFF, a control code other than whitespace, or a noncharacter. SEARCH_FOLD_VERSION is now 2.

    Every other string the engine returns ends its lines in \n too: an annotation's contents (its rich text's plain projection joins paragraphs with \n) and a hard line break inside a rich text run, which RichTextRun.text now spells \n.

  • #1005 by @bobsingor – A PDF's permissions are named flags, PdfPermissionFlags: print, modifyContents, copy, modifyAnnotations, fillForms, copyForAccessibility, assemble and printHighQuality (pdf.js's names), replacing PdfBits and its bit3…bit12. A document head's and security state's permissions.flags replaces the raw bits word, and PdfPermissionInfo carries flags with no bits. The advisory (canPrint, …) and advisoryFromPdfBits() are gone: materializePdfPermissions(flags) says what pdf.permissions grants. permissionFlagsOf(word) replaces decodePdfBits(), and the permission checks take permissionFlags.

  • #982 by @bobsingor – A widget reads hasMark: true when it is a signature field's widget with a mark in it, because the field is signed or a mark was drawn in with forms.setSignatureAppearance. A new signature field's widget is predicted with its appearance (its box), and WIDGET_STYLE_NAMES lists the fields that make up a widget's style.

  • #990 by @bobsingor – Responses are read tolerantly, as docs/conventions/api-evolution.md asks, so a client keeps working against a newer server. No schema a response is parsed with refuses a field it doesn't know any more, nested ones included (LineLeaderSchema, a measure's origin, IdentitySchema, RedactionApplyScopeSchema, BundleLimitsSchema, ImageResourceKeysSchema); requests are still parsed strictly, with LineLeaderWriteSchema, IdentityInputSchema and RedactionApplyScopeInputSchema.

    An annotation of a subtype the client doesn't know reads as unsupported instead of failing the whole list, keeping the fields every annotation has, with rawSubtypeCode and rawSubtypeName from the body when it carries them and 0 and null when it doesn't. A subtype the client knows with a malformed body still fails. The other sets with a catch-all read the same way: an error code as Unknown, a widget's fieldFamily and a form field's family as unknown, a measure as unknown, a link or outline target as unsupported, an action as unknown and a field's value entry as unsupported.

    Every other enum, literal and union a response carries is marked closed with the new closed(), next to readsUnknownAs() and withCatchAll() for open ones, and readingProblems() and withUnknownFields() in @embedpdf/engine-core/conformance check a schema against the convention.

  • #1003 by @bobsingor – FormField (with TextField, CheckboxField, RadioField, ComboBoxField, ListBoxField, PushButtonField, SignatureField and UnknownField) and Signature replace the …DTO names. The deprecated Point, Rect, Size and Rotation aliases and PointSchema/RectSchema are gone: use the Pdf… names. Exported functions take options, never opts.

  • #1002 by @bobsingor – A form field is tagged kind, not family, as naming.md tags things that are: field.kind === 'checkbox', the type FormFieldKind, a draft's and a patch's kind, and a widget annotation's fieldKind. A values import's diagnostics say unsupported-kind and wrong-kind.

  • #992 by @bobsingor – API_VERSION is the version this release speaks, the major and minor of its package version, with parseApiVersion and apiVersionOf to read one.

  • #1000 by @bobsingor – An event's origin spells out its fields: subject (was sub), at as an ISO 8601 string (was ts, milliseconds), serverSequence (was serverId) and transaction (was tx); stream.desynced carries at, and the event stream's lastServerSequence() replaces lastServerId(). A grant's callbacks are onIdentityRequested and onOpenRequested, and resume() takes visitorIdentity. Render results and appearance pictures say mimeType, as attachments and stamps do (was contentType).

Patch Changes

  • #999 by @bobsingor – A widget's dashArray doc says what the code does: left out on a dashed border is the default pattern, and null is no pattern.

@embedpdf/engine-services@3.0.0-next.23

Minor Changes

  • #982 by @bobsingor – A signature field draws its box: placing one writes its background and border, and a restyle draws them again, as it does for a widget in no field. Once a mark is in the field (it is signed, or a mark was drawn in), the mark stays: a resize keeps it, and a style change is refused with InvalidArg. A mark drawn in records how it fits the widget, as a stamp records its own.

  • #1000 by @bobsingor – A worker image encoder's result says mimeType (was contentType), as render results do.

Patch Changes

  • #997 by @bobsingor – Reads and writes a submit-form action's flags by name, and says the renamed fields (sizeBytes, md5, displaySha256, contentsSizeBytes, changedRefs, the seed value's booleans).

  • #995 by @bobsingor – A stamping import still puts an item in no group in the caller's group, now that an annotation create's groupId: null asks for no group, and still gives each copy a fresh name, now that nm: null asks for none.

  • #985 by @bobsingor – Page text comes from toPageText: lines end in \n, and noncharacters such as the U+FFFE PDFium writes for a joined line-end hyphen give no text. An annotation's /Contents reads with \n line breaks and is written with \r, as Acrobat writes it. Hard line breaks in rich text runs read as \n and are written as \r.

  • #1003 by @bobsingor – Follows engine-core's names.

  • #1002 by @bobsingor – Follows engine-core: form fields are tagged kind.

@embedpdf/angular@3.0.0-next.23

Minor Changes

  • #999 by @bobsingor – The viewer takes null for identity and scope, as its settings read them: identity: null is nobody, and scope: null lets the user do everything.

  • #1003 by @bobsingor – Follows the plugins: CommandDefinition, FormField, selectionHandleGeometry, CustomSlotContext, and an actions adapter's goToPage(pageIndex).

  • #1000 by @bobsingor – Follows the plugins: EpdfAttachment has create, delete, canCreate and canDelete; EpdfViewManager has deletePane and paneDeleted$; EpdfLink.readAllLinks, EpdfStamp.getAssetBytes, EpdfFonts.readProgram, EpdfActions.readActionTree; a command's shortcutLabel.

@embedpdf/react@3.0.0-next.23

Minor Changes

  • #999 by @bobsingor – The viewer takes null for identity and scope, as its settings read them: identity: null is nobody, and scope: null lets the user do everything.

  • #1003 by @bobsingor – Follows the plugins: CommandDefinition, FormField, selectionHandleGeometry, CustomSlotContext, and an actions adapter's goToPage(pageIndex).

Patch Changes

  • #1000 by @bobsingor – Follows the plugins: the attachment state's canCreate, OverflowRow.kind, destroy().

@embedpdf/svelte@3.0.0-next.23

Minor Changes

  • #999 by @bobsingor – The viewer takes null for identity and scope, as its settings read them: identity: null is nobody, and scope: null lets the user do everything.

  • #1003 by @bobsingor – Follows the plugins: CommandDefinition, FormField, selectionHandleGeometry, CustomSlotContext, and an actions adapter's goToPage(pageIndex).

Patch Changes

  • #1000 by @bobsingor – Follows the plugins: the attachment state's canCreate, OverflowRow.kind, destroy().

@embedpdf/vue@3.0.0-next.23

Minor Changes

  • #999 by @bobsingor – The viewer takes null for identity and scope, as its settings read them: identity: null is nobody, and scope: null lets the user do everything.

  • #1003 by @bobsingor – Follows the plugins: CommandDefinition, FormField, selectionHandleGeometry, CustomSlotContext, and an actions adapter's goToPage(pageIndex).

Patch Changes

  • #1000 by @bobsingor – Follows the plugins: the attachment state's canCreate, OverflowRow.kind, destroy().

@embedpdf/web@3.0.0-next.23

Minor Changes

  • #1003 by @bobsingor – An actions adapter's page move is goToPage(pageIndex, context). Follows core-geometry: Rotation.

  • #1000 by @bobsingor – The printer ends with destroy(). A page projector's stage is read through getPageBox(), and a link anchor dispatches { type: 'annotation', annotation }, as the actions plugin's triggers are.

Patch Changes

  • #985 by @bobsingor – The rich text editor reads a hard line break, however the browser spells it, as \n, and its offsets count paragraphs joined by \n, matching the rich text the engine returns.

@embedpdf/plugin-actions@3.0.0-next.23

Minor Changes

  • #997 by @bobsingor – SubmitIntent and ActionSubmitRequest drop flagsRaw: an intent's format, method and resolved fields already say what the flags meant.

  • #1003 by @bobsingor – The UI adapter's page move is goToPage(pageIndex, context) (was gotoPage(page, …)). The host contract's AnnotationCommitEntry, AnnotationCommitResult and AnnotationCommitSink are spelled out. Read shapes are readonly.

  • #1000 by @bobsingor – readActionTree() replaces getActionTree(): a read from the engine is read*. ActionTrigger and ActionTriggerEvent are tagged type (was scope); a trigger's annotation is annotation (was ref) and an event's name is event (was name), as ActionTreeSource says. The host contract's realm ends with destroy().

@embedpdf/plugin-annotation@3.0.0-next.23

Minor Changes

  • #999 by @bobsingor – chrome.marquee is one look: a change replaces it whole, and a color it leaves out follows the accent again. The other chrome groups still merge per key.

  • #1003 by @bobsingor – The sub-capabilities are AnnotationSelectionCapability, AnnotationDraftCapability, AnnotationTextCapability, AnnotationToolsCapability, AnnotationStampsCapability, AnnotationLinksCapability and CommentsCapability (were …Api). AnnotationToolDefinition replaces AnnotationToolDef. Read shapes are readonly.

  • #1000 by @bobsingor – The selection is selection.select(refs) and selection.getSelected(), as page-edit, attachment and outline have them (was set and list). CommentThreadChangedEvent is tagged type (was change). The host contract's functions start with a verb: getAuthority, getPictureEpoch, getPictureVersion, isPending, getDistanceCreationPage. The snap settings are alignmentThresholdPx and rotationThresholdDeg.

Patch Changes

  • #982 by @bobsingor – A lent record with no live drawing keeps its picture while a new look is pending, instead of drawing its bare style in its place.

@embedpdf/plugin-attachment@3.0.0-next.23

Minor Changes

  • #1000 by @bobsingor – Attachments are created and deleted, as the engine's attachments.create/delete say: create(), delete(), canCreate(), canDelete() and the state's canCreate (were add, remove, canAdd, canRemove). onChanged says 'created' and 'deleted'.

Patch Changes

@embedpdf/plugin-commands@3.0.0-next.23

Minor Changes

  • #1006 by @bobsingor – A command can have labelParams(context): the values for its label's {name} slots, such as how many pages are selected. It's asked like enabled, again whenever the viewer's state or your app's changes. The values go into label, into the translated words under labelKey or the command's id, where a number count picks the plural form, and into every sentence that names the label. A labelParams that throws gives no values. Without the i18n plugin, label's slots are filled too.

  • #1003 by @bobsingor – CommandDefinition replaces CommandDef.

  • #1000 by @bobsingor – A bound command's formatted shortcut is shortcutLabel; shortcut stays the key a command definition takes.

@embedpdf/plugin-fonts@3.0.0-next.23

Minor Changes

  • #1000 by @bobsingor – readProgram() replaces getProgram(): a read from the engine is read*.

Patch Changes

  • #997 by @bobsingor – Reads a program's displaySha256 and sourceSha256.

@embedpdf/plugin-form@3.0.0-next.23

Minor Changes

  • #1003 by @bobsingor – FormToolDefinition replaces FormToolDef, and form fields are FormField. Read shapes are readonly.

  • #1002 by @bobsingor – Form fields are tagged kind: list({ kind }), the fillable setting's field kinds (FormFieldKind), a form tool's fieldKind and AuthorableFormKind.

  • #1000 by @bobsingor – WidgetActivationResult is tagged status, as every call result is (was kind). FormUiEffect is tagged type. The scripting realm ends with destroy().

Patch Changes

  • #997 by @bobsingor – A scripted submit no longer sends flagsRaw.

  • #982 by @bobsingor – In design mode a restyled signature field shows its new look at once and keeps it, instead of flashing it and going back. A signature field with a mark in it is drawn only by its picture.

@embedpdf/plugin-i18n@3.0.0-next.23

Minor Changes

  • #1004 by @bobsingor – A fallback language in loaders now loads at the start, and a language shows once it and the fallback language are in, so a lazy fallback language no longer shows keys in place of its strings. Until then the fallback language shows, or, while that loads too, the first language in locales. A language in both locales and loaders shows its locales strings until its loader has run, and the loader's language then replaces them. When the fallback language can't load, onLocaleLoadFailed fires and languages show without it.

  • #1006 by @bobsingor – interpolate(text, params) fills a string's {name} slots as t() does, for text that has no translation. TranslateOptions.params takes a readonly record.

Patch Changes

@embedpdf/plugin-interaction@3.0.0-next.23

Minor Changes

  • #1000 by @bobsingor – An InteractionHandler says onPointerDown, onPointerMove, onPointerUp and onPointerCancel, as a Tool does (was onDown, onMove, onUp, onCancel).

Patch Changes

@embedpdf/plugin-link@3.0.0-next.23

Minor Changes

  • #1003 by @bobsingor – Read shapes are readonly.

  • #1000 by @bobsingor – readAllLinks() replaces listAllLinks(): a read from the engine is read*. LinkActivation is tagged status, as every call result is (was outcome).

@embedpdf/plugin-measurement@3.0.0-next.23

Minor Changes

Patch Changes

  • #1000 by @bobsingor – Follows core's settings events (changedKeys) and mirror specs (onChanged).

@embedpdf/plugin-render@3.0.0-next.23

Minor Changes

  • #999 by @bobsingor – The format and quality settings read null while the engine chooses, so updateSettings({ format: null }) gives the choice back; they used to read undefined, which a change could never set. snapshot.box is one look: a change replaces it whole, and a color it leaves out follows the accent again.

  • #1003 by @bobsingor – The full-page and tile settings types are FullPageSettings and TilesSettings (were …Options).

  • #1000 by @bobsingor – The tile settings name their units: bleedPx and engageRatio (were bleed and engageAt). Results say mimeType. The host contract's view demand ends with destroy(), and getKeptAppearances() starts with a verb.

@embedpdf/plugin-search@3.0.0-next.23

Minor Changes

  • #1003 by @bobsingor – highlight.blendMode is engine-core's BlendMode; the SearchBlendMode copy is gone.

  • #1000 by @bobsingor – refresh() resolves nothing, as every plugin's does; the result is in the state and the events.

Patch Changes

  • #983 by @bobsingor – A search asks for snippets only when the session may copy text (doc.text.copy). Before, it always asked for them first and, when refused, searched again without them: two requests for every search in a session without copy rights. findAll(query, { snippets: true }) now refuses with permission-denied (naming doc.text.copy) without asking the engine. If the engine still refuses snippets the session looked allowed to have, the search falls back to matches without them as before.

@embedpdf/plugin-selection@3.0.0-next.23

Minor Changes

  • #1003 by @bobsingor – SelectionHandleGeometry and selectionHandleGeometry() replace the …Geom names. Read shapes are readonly.

  • #1000 by @bobsingor – The drag setting names its unit: dragThresholdPx.

@embedpdf/plugin-signature@3.0.0-next.23

Minor Changes

  • #1003 by @bobsingor – getSignature() returns SignatureInfo, as listSignatures() does: the field's facts and its verdict (null until checked, or for an unsigned field). The PreparedSignature alias is gone: prepareSignature() resolves SignaturePrepared.

  • #1000 by @bobsingor – refresh() resolves nothing, as every plugin's does. The signing key is signingKey (setting and sign() option) and its type SigningKey (were key and SignatureKey: in naming.md a key is a lookup key). PlaceMarkResult is tagged status, as every call result is (was kind). validate() takes validationTime (was at).

Patch Changes

  • #1002 by @bobsingor – Follows engine-core: form fields are tagged kind.

@embedpdf/plugin-stage@3.0.0-next.23

Minor Changes

  • #999 by @bobsingor – reveal()'s rect is rect?: Rect: left out is the whole page, and null is no longer taken. A zoomBox change that gives a color as undefined follows the accent, instead of storing undefined.

  • #1003 by @bobsingor – Read shapes are readonly, the settings included. Follows core-geometry and core-stage: Rotation, PageGeometry.

  • #1000 by @bobsingor – StageViewState.pageIndex replaces cursor. getPageBox() replaces getPageFrame(), since PageFrame is a setting. A reveal's alignment is align?: RevealAlignment, its values ArrivalAlignValue (were anchor, RevealAnchor and RevealAnchorValue, a copy of it). Settings events carry changedKeys.

@embedpdf/plugin-stamp@3.0.0-next.23

Minor Changes

  • #1003 by @bobsingor – createAsset() takes CreateAssetInput (was AddAssetInput). Read shapes are readonly.

  • #1000 by @bobsingor – getAssetBytes() replaces readAssetBytes(): it's synchronous. StampLibraryChangedEvent is tagged type (was reason) and says 'asset-created', 'asset-deleted' and 'deleted', as onAssetCreated, onAssetDeleted and onLibraryDeleted do. ImportLibraryOptions.assetKind replaces kind, which CreateLibraryOptions uses for the library's.

@embedpdf/plugin-view-manager@3.0.0-next.23

Minor Changes

  • #1000 by @bobsingor – deletePane(), DeletePaneOptions, onPaneDeleted and PaneDeletedEvent pair with createPane() (were removePane, RemovePaneOptions, onPaneRemoved and PaneRemovedEvent).

@embedpdf/viewer-chrome@3.0.0-next.23

Minor Changes

  • #999 by @bobsingor – The viewer takes null for identity and scope, as its settings read them: identity: null is nobody, and scope: null lets the user do everything.

  • #1003 by @bobsingor – A viewer command is a CommandDefinition (was CommandDef).

  • #1006 by @bobsingor – A command of yours can have labelParams, which gets the same context as enabled: plugins by name through get, your appState, the document and the viewer. Its values fill the {name} slots in the command's label, and a number count picks the plural form of translated words.

  • #1004 by @bobsingor – strings takes a language's words as a function that loads them the first time the language shows, and plugins.i18n.fallbackLocale sets the fallback language, also shown when the browser asks for none of the viewer's languages. plugins.i18n takes only fallbackLocale. document:download saves the document under its name.

  • #1000 by @bobsingor – ViewerLifetime.destroy() replaces dispose(). The signature setting's key is signingKey.

  • #1011 by @bobsingor – Selected redaction marks can be applied from the annotation bar: its new annotation:apply-redaction command shows when every selected annotation is a redaction mark, and asks first in the same confirmation as redaction:apply, counting only those marks and the other annotations under them. The confirmation's title takes plural forms in strings now (demo.redactConfirmTitle), and the command's label is commands.redact.apply, such as { one: 'Apply Redaction', other: 'Apply {count} Redactions' }.

Patch Changes

  • #1009 by @bobsingor – A comment without an author shows as "Guest" instead of "Unknown", in every language, as it did in v2.

  • #997 by @bobsingor – The attachments panel reads a file's sizeBytes.

  • #1001 by @bobsingor – On a phone, a submenu opened in a menu's sheet covers the menu under it completely. Before, once it finished sliding in, the rows of the menu under it that open submenus showed through its top rows.

  • #1002 by @bobsingor – Follows engine-core: form fields are tagged kind.

  • #1007 by @bobsingor – Counts read right in every language: the number of files and comments, search results, redaction marks and selected annotations each pick their language's plural form, such as Polish's few and many and Arabic's six forms, instead of choosing between a singular and a plural word or a "Label: 3" wording. attachments.countPlural and comments.countPlural are gone: attachments.count, comments.count, demo.searchResults, demo.redactConfirmBody, demo.redactConfirmCollateral and stylePanel.selected take plural forms in strings, such as { one: '{count} file', other: '{count} files' }.

@embedpdf/viewer@3.0.0-next.23

Minor Changes

  • #1004 by @bobsingor – strings takes a language's words as a function too, such as sv: () => import('./sv.json'): they load the first time the viewer shows that language, which shows once they're in. plugins.i18n.fallbackLocale sets the fallback language, one of the viewer's or one of yours: the language a browser gets when the viewer has none of its languages, and where every word the current language doesn't have comes from. It loads at the start. plugins.i18n takes only fallbackLocale now; the languages are locale and strings, and other keys are left out with a warning. The viewer's English words ship as @embedpdf/viewer/strings/en.json, to start a translation from. A download is saved under the document's name instead of document.pdf.

Patch Changes

  • #1003 by @bobsingor – Follows the viewer chrome: CommandDefinition.

  • #1000 by @bobsingor – Follows the viewer chrome: the signature setting's key is signingKey.

@cloudpdf/server-modules@3.0.0-next.23

Patch Changes

  • #997 by @bobsingor – The test server seeds its documents with the init request's sizeBytes.

  • #1002 by @bobsingor – The test server reads the init answer's status.

@embedpdf/core-fonts@3.0.0-next.23

Patch Changes

  • #997 by @bobsingor – A built-in program's facts say displaySha256.

@embedpdf/engine@3.0.0-next.23

Patch Changes

  • #997 by @bobsingor – Asks the worker for a font program by its displaySha256.

  • #1005 by @bobsingor – Follows engine-core: permissions are named flags.

  • #1003 by @bobsingor – Follows engine-core's names. createLocalEngine(options) and the other factories take options.

  • #1000 by @bobsingor – Follows engine-core: encoded pictures say mimeType.

@embedpdf/plugin-history@3.0.0-next.23

Patch Changes

@embedpdf/plugin-metadata@3.0.0-next.23

Patch Changes

@embedpdf/plugin-outline@3.0.0-next.23

Patch Changes

  • #997 by @bobsingor – Reads a mutation's changedRefs.

  • #1000 by @bobsingor – Activating an item resolves a LinkActivation tagged status. Follows core's mirror specs (onChanged) and pagesSequence.

@embedpdf/plugin-redaction@3.0.0-next.23

Patch Changes

@embedpdf/viewer-react@3.0.0-next.23

Patch Changes

@cloudpdf/web@3.0.0-next.23

@cloudpdf/plugin-protected-display@3.0.0-next.23

@cloudpdf/viewer-angular@3.0.0-next.23

@cloudpdf/viewer@3.0.0-next.23

@cloudpdf/viewer-react@3.0.0-next.23

@cloudpdf/viewer-svelte@3.0.0-next.23

@cloudpdf/viewer-vue@3.0.0-next.23

@embedpdf/engine-runtime@3.0.0-next.23

@embedpdf/engine-runtime-darwin-arm64@3.0.0-next.23

@embedpdf/engine-runtime-darwin-x64@3.0.0-next.23

@embedpdf/engine-runtime-linux-arm64@3.0.0-next.23

@embedpdf/engine-runtime-linux-x64@3.0.0-next.23

@embedpdf/engine-runtime-linuxmusl-arm64@3.0.0-next.23

@embedpdf/engine-runtime-linuxmusl-x64@3.0.0-next.23

@embedpdf/engine-runtime-wasm32@3.0.0-next.23

@embedpdf/engine-runtime-win32-arm64@3.0.0-next.23

@embedpdf/engine-runtime-win32-x64@3.0.0-next.23

@embedpdf/plugin-page-edit@3.0.0-next.23

@embedpdf/plugin-shell@3.0.0-next.23

@embedpdf/viewer-angular@3.0.0-next.23

@embedpdf/viewer-svelte@3.0.0-next.23

@embedpdf/viewer-vue@3.0.0-next.23