textmode.export.js 1.9.0-beta.1 → 1.9.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -0
- package/dist/textmode.document.esm.js +1 -0
- package/dist/textmode.export.esm.js +1 -1
- package/dist/textmode.export.umd.js +1 -1
- package/dist/types/document/constants.d.ts +32 -0
- package/dist/types/document/decode-shapes.d.ts +4 -0
- package/dist/types/document/decode.d.ts +5 -0
- package/dist/types/document/index.d.ts +13 -0
- package/dist/types/document/parse.d.ts +3 -0
- package/dist/types/document/types.d.ts +209 -0
- package/dist/types/document/validation.d.ts +37 -0
- package/dist/types/exporters/base/LayerTarget.d.ts +0 -2
- package/dist/types/exporters/gif/types.d.ts +0 -4
- package/dist/types/exporters/image/types.d.ts +0 -2
- package/dist/types/exporters/json/types.d.ts +14 -204
- package/dist/types/exporters/svg/types.d.ts +1 -3
- package/dist/types/exporters/txt/types.d.ts +0 -2
- package/dist/types/exporters/video/types.d.ts +0 -20
- package/dist/types/exporters/zip/errors.d.ts +0 -1
- package/dist/types/exporters/zip/types.d.ts +0 -7
- package/dist/types/index.d.ts +3 -27
- package/dist/types/types.d.ts +0 -28
- package/package.json +46 -10
- package/protocol/textmode-document/2.0/SPECIFICATION.md +233 -0
- package/protocol/textmode-document/2.0/fixture.d.ts +3 -0
- package/protocol/textmode-document/2.0/fixtures/textmode-document-all-v2.json +94 -0
- package/protocol/textmode-document/2.0/fixtures/textmode-document-create-integration-v2.json +112 -0
- package/protocol/textmode-document/2.0/fixtures/textmode-document-selected-v2.json +86 -0
- package/protocol/textmode-document/2.0/fixtures/textmode-layer-all-v1.1.json +46 -0
- package/protocol/textmode-document/2.0/fixtures/textmode-layer-selected-v1.json +38 -0
- package/protocol/textmode-document/2.0/textmode-document-2.0.schema.d.ts +3 -0
- package/protocol/textmode-document/2.0/textmode-document-2.0.schema.json +171 -0
package/README.md
CHANGED
|
@@ -24,6 +24,10 @@ Choose a compact still, structured document data, or a complete animation to sui
|
|
|
24
24
|
- **Controlled animation capture** - Configure frames, frame rate, scale, GIF repetition, video encoding, transparency, progress, and more
|
|
25
25
|
- **ZIP frame sequences** - Archive deterministic PNG, JPEG, WebP, SVG, JSON, or TXT frames with a versioned manifest
|
|
26
26
|
|
|
27
|
+
The [textmode document 2.0 specification](./protocol/textmode-document/2.0/SPECIFICATION.md) defines the editable
|
|
28
|
+
JSON format, its schema, and the published compatibility fixtures. The dependency-free decoder is available from the
|
|
29
|
+
ESM-only `textmode.export.js/document` entry point.
|
|
30
|
+
|
|
27
31
|
## Try it online first
|
|
28
32
|
|
|
29
33
|
Open [editor.textmode.art](https://editor.textmode.art/), a browser-based live-coding environment for the
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var e="textmode.document",t="2.0.0",r="textmode.layer",n="1.0.0",a="1.1.0",o="object-rows-v1",i={maxCells:16777216,maxLayers:4096,maxLayerIdLength:1024,maxCharacterLength:64,maxMetadataStringLength:4096},s=class extends Error{detail;constructor(e){super(e.message),this.detail=e}};function c(e,t){if("string"==typeof e){const r=/^#([0-9a-f]{6}|[0-9a-f]{8})$/i.exec(e);r||b("INVALID_DOCUMENT","Expected #RRGGBB or #RRGGBBAA color notation.",t);const n=r[1];return{r:Number.parseInt(n.slice(0,2),16),g:Number.parseInt(n.slice(2,4),16),b:Number.parseInt(n.slice(4,6),16),a:8===n.length?Number.parseInt(n.slice(6,8),16):255}}const r=I(e,t);return{r:T(r.r,`${t}.r`),g:T(r.g,`${t}.g`),b:T(r.b,`${t}.b`),a:T(r.a,`${t}.a`)}}function l(e,t){const r=I(e,t);return{width:A(r.width,`${t}.width`),height:A(r.height,`${t}.height`)}}function m(e,t){const r=I(e,t);return{cols:A(r.cols,`${t}.cols`),rows:A(r.rows,`${t}.rows`),cellWidth:A(r.cellWidth,`${t}.cellWidth`),cellHeight:A(r.cellHeight,`${t}.cellHeight`)}}function d(e,t,r){const n=I(e,t),a=I(n.generator,`${t}.generator`),o=N(a.name,`${t}.generator.name`,r.maxMetadataStringLength),i=N(n.createdAt,`${t}.createdAt`,r.maxMetadataStringLength);return function(e,t){const r=u.exec(e);r||b("INVALID_DOCUMENT","Expected an uppercase RFC 3339 timestamp with seconds and a timezone.",t);const n=Number(r[1]),a=Number(r[2]);Number(r[3])>[31,n%4!=0||n%100==0&&n%400!=0?28:29,31,30,31,30,31,31,30,31,30,31][a-1]&&b("INVALID_DOCUMENT","Timestamp contains an invalid calendar date.",t)}(i,`${t}.createdAt`),{createdAt:i,generator:{name:o,version:N(a.version,`${t}.generator.version`,r.maxMetadataStringLength)}}}var u=/^([0-9]{4})-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9](?:\.[0-9]+)?(?:Z|[+-](?:[01][0-9]|2[0-3]):[0-5][0-9])$/;function g(e,t,r){return N(e,t,r.maxLayerIdLength)}function f(e,t,r){const n=$(t.cols,t.cellWidth,`${r}.width`),a=$(t.rows,t.cellHeight,`${r}.height`);e.width===n&&e.height===a||b("INVALID_DOCUMENT",`Canvas must equal the grid pixel extent ${n}x${a}.`,r)}function h(e,t,r){if(void 0===e)return t;if(!Number.isSafeInteger(e)||e<=0)throw new TypeError(`${r} must be a positive safe integer.`);return e}function $(e,t,r){const n=e*t;return Number.isSafeInteger(n)||b("LIMIT_EXCEEDED","Numeric dimensions exceed the safe integer range.",r),n}function x(e){const t=(e%360+360)%360;return Object.is(t,-0)?0:t}function I(e,t){return("object"!=typeof e||null===e||Array.isArray(e))&&b("INVALID_DOCUMENT","Expected an object.",t),e}function E(e,t){return Array.isArray(e)||b("INVALID_DOCUMENT","Expected an array.",t),e}function p(e,t){return"string"!=typeof e&&b("INVALID_DOCUMENT","Expected a string.",t),e}function N(e,t,r){const n=p(e,t);return 0===n.length&&b("INVALID_DOCUMENT","Expected a non-empty string.",t),n.length>r&&b("LIMIT_EXCEEDED",`String length exceeds the configured limit ${r}.`,t),n}function L(e,t,r){const n=p(e,t);return 0===n.length&&b("INVALID_DOCUMENT","Expected a non-empty glyph string.",t),function(e,t){for(let r=0;r<e.length;r++){const n=e.charCodeAt(r);if(n>=55296&&n<=56319){const n=e.charCodeAt(r+1);(!Number.isInteger(n)||n<56320||n>57343)&&b("INVALID_DOCUMENT","Glyph strings must not contain unpaired surrogates.",t),r++;continue}n>=56320&&n<=57343&&b("INVALID_DOCUMENT","Glyph strings must not contain unpaired surrogates.",t)}}(n,t),Array.from(n).length>r.maxCharacterLength&&b("LIMIT_EXCEEDED",`Glyph string scalar count exceeds the configured limit ${r.maxCharacterLength}.`,t),n}function D(e,t){return"boolean"!=typeof e&&b("INVALID_DOCUMENT","Expected a boolean.",t),e}function y(e,t){return"number"==typeof e&&Number.isFinite(e)||b("INVALID_DOCUMENT","Expected a finite number.",t),e}function C(e,t,r,n){const a=y(e,t);return(a<r||a>n)&&b("INVALID_DOCUMENT",`Expected a number from ${r} through ${n}.`,t),a}function M(e,t){return"number"==typeof e&&Number.isSafeInteger(e)||b("INVALID_DOCUMENT","Expected a safe integer.",t),e}function A(e,t){const r=M(e,t);return r<=0&&b("INVALID_DOCUMENT","Expected a positive safe integer.",t),r}function T(e,t){const r=M(e,t);return(r<0||r>255)&&b("INVALID_DOCUMENT","Expected an integer from 0 through 255.",t),r}function b(e,t,r){throw new s({code:e,message:t,...r?{path:r}:{}})}function v(r,n){const a=l(r.canvas,"$.canvas"),o=m(r.grid,"$.grid");f(a,o,"$.canvas");const i=I(r.layer,"$.layer");return{format:e,formatVersion:t,target:"selected",...void 0===r.metadata?{}:{metadata:d(r.metadata,"$.metadata",n.limits)},canvas:a,grid:o,layer:{id:g(i.id,"$.layer.id",n.limits),cells:O(i.cells,o,"$.layer.cells",n)}}}function U(r,n){const a=l(r.canvas,"$.canvas"),o=E(r.layers,"$.layers");0===o.length&&b("INVALID_DOCUMENT","A layer-stack document must contain at least one layer.","$.layers"),o.length>n.limits.maxLayers&&b("LIMIT_EXCEEDED",`Layer count ${o.length} exceeds the configured limit ${n.limits.maxLayers}.`,"$.layers");const i=o.map((e,t)=>function(e,t,r){const n=I(e,t),a=m(n.grid,`${t}.grid`);return{id:g(n.id,`${t}.id`,r.limits),visible:D(n.visible,`${t}.visible`),opacity:C(n.opacity,`${t}.opacity`,0,1),blendMode:N(n.blendMode,`${t}.blendMode`,r.limits.maxMetadataStringLength),offsetX:y(n.offsetX,`${t}.offsetX`),offsetY:y(n.offsetY,`${t}.offsetY`),rotationZ:y(n.rotationZ,`${t}.rotationZ`),grid:a,cells:O(n.cells,a,`${t}.cells`,r)}}(e,`$.layers[${t}]`,n));return f(a,i[0].grid,"$.canvas"),{format:e,formatVersion:t,target:"all",...void 0===r.metadata?{}:{metadata:d(r.metadata,"$.metadata",n.limits)},canvas:a,layers:i}}function O(e,t,r,n){const a=I(e,r),i=p(a.encoding,`${r}.encoding`);"object-rows-v1"!==i&&b("UNSUPPORTED_ENCODING",`Unsupported cell encoding: ${i}.`,`${r}.encoding`);const s=$(t.cols,t.rows,`${r}.rows`);s>n.remainingCells&&b("LIMIT_EXCEEDED",`Document cell count exceeds the configured limit ${n.limits.maxCells}.`,`${r}.rows`),n.remainingCells-=s;const l=E(a.rows,`${r}.rows`);return l.length!==t.rows&&b("INVALID_DOCUMENT",`Expected ${t.rows} cell rows, received ${l.length}.`,`${r}.rows`),{encoding:o,rows:l.map((e,a)=>{const o=`${r}.rows[${a}]`,i=E(e,o);return i.length!==t.cols&&b("INVALID_DOCUMENT",`Expected ${t.cols} cells, received ${i.length}.`,o),i.map((e,t)=>function(e,t,r,n,a){const o=I(e,n),i=M(o.x,`${n}.x`),s=M(o.y,`${n}.y`);i===t&&s===r||b("INVALID_DOCUMENT",`Cell coordinates must match their row position (${t}, ${r}).`,n);const l=I(o.transform,`${n}.transform`);return{x:i,y:s,character:L(o.character,`${n}.character`,a.limits),foreground:c(o.foreground,`${n}.foreground`),background:c(o.background,`${n}.background`),transform:{invert:D(l.invert,`${n}.transform.invert`),flipX:D(l.flipX,`${n}.transform.flipX`),flipY:D(l.flipY,`${n}.transform.flipY`),rotation:x(y(l.rotation,`${n}.transform.rotation`))}}}(e,t,a,`${o}[${t}]`,n))})}}function _(e){try{return{ok:!0,value:JSON.parse(e)}}catch(t){return{ok:!1,error:{code:"INVALID_JSON",message:t instanceof Error?t.message:"The file is not valid JSON."}}}}function V(e,t={}){try{const r=function(e){return{maxCells:h(e?.maxCells,i.maxCells,"maxCells"),maxLayers:h(e?.maxLayers,i.maxLayers,"maxLayers"),maxLayerIdLength:h(e?.maxLayerIdLength,i.maxLayerIdLength,"maxLayerIdLength"),maxCharacterLength:h(e?.maxCharacterLength,i.maxCharacterLength,"maxCharacterLength"),maxMetadataStringLength:h(e?.maxMetadataStringLength,i.maxMetadataStringLength,"maxMetadataStringLength")}}(t.limits),n={limits:r,remainingCells:r.maxCells},a=I(e,"$"),o=p(a.format,"$.format");return"textmode.document"===o?{ok:!0,document:S(a,n),warnings:[]}:"textmode.layer"===o&&(t.acceptLegacy??!0)?{ok:!0,document:R(a,n),warnings:[{code:"LEGACY_DOCUMENT_MIGRATED",message:"Migrated a legacy textmode.layer document to textmode.document 2.0.0."}]}:{ok:!1,error:{code:"UNSUPPORTED_FORMAT",message:`Unsupported textmode document format: ${o}.`,..."$.format"?{path:"$.format"}:{}}}}catch(r){if(r instanceof s)return{ok:!1,error:r.detail};throw r}}function w(e,t={}){const r=_(e);return r.ok?V(r.value,t):r}function S(e,t){const r=p(e.formatVersion,"$.formatVersion");"2.0.0"!==r&&b("UNSUPPORTED_VERSION",`Unsupported textmode.document version: ${r}.`,"$.formatVersion");const n=p(e.target,"$.target");return"selected"===n?v(e,t):"all"===n?U(e,t):void b("UNSUPPORTED_TARGET",`Unsupported textmode document target: ${n}.`,"$.target")}function R(e,t){const r=p(e.formatVersion,"$.formatVersion");return"1.0.0"===r?v(e,t):"1.1.0"===r?U(e,t):void b("UNSUPPORTED_VERSION",`Unsupported legacy textmode.layer version: ${r}.`,"$.formatVersion")}export{i as DEFAULT_TEXTMODE_DOCUMENT_LIMITS,a as LEGACY_TEXTMODE_ALL_VERSION,r as LEGACY_TEXTMODE_LAYER_FORMAT,n as LEGACY_TEXTMODE_SELECTED_VERSION,e as TEXTMODE_DOCUMENT_FORMAT,t as TEXTMODE_DOCUMENT_FORMAT_VERSION,o as TEXTMODE_OBJECT_ROWS_ENCODING,V as decodeTextmodeDocument,_ as parseJSON,w as parseTextmodeDocumentJSON};
|