appcore-filemaker
BETA PÚBLICA —
0.1.0-beta.2está disponível no crates.io para avaliação.
appcore-filemaker 0.1.0-beta.2 é o compilador determinístico oficial do
AppCore para documentos declarativos, canvases vetoriais e datasets. A versão
0.1.0-beta.2 está publicada no crates.io e permanece fora do Runtime estável.
Se você está começando no formato, siga o guia YAML passo a passo. Ele parte do cabeçalho mínimo e avança por dados, estilos, vetores, tabelas, papéis de página, imagens, colisão, componentes e preflight estrito. O final traz a referência completa de campos e identifica os nodes reservados que ainda não estão implementados.
YAML estrito filemaker: "1.0", dados tipados e patches atômicos compilam para
IR tipada. Fontes e assets explícitos são medidos antes do layout fixed-point,
colisão/reflow por geometria e construção da ResolvedScene imutável.
Inspeção, validação, preflight e exporter consomem a cena sem mudar geometria.
Canvas é um contrato de desenho semântico, não um buffer de pixels. Coordenadas
aceitam pt, px, mm, cm, in, %, lu lógico e valores
norm/normalized limitados a 0..=1. Text, image, line, rect, circle,
ellipse, polygon, path e group permanecem nós tipados; paths preservam comandos
move, line, curve cúbica e close. Circle exige eixos resolvidos iguais. Safe
area, presets, layers/z-index, transforms e colisão são entradas explícitas e
ortogonais.
As cores permanecem independentes do formato como RGB, RGBA, Gray ou CMYK em
milionésimos. O YAML aceita nomes estáveis, hex, notação funcional inteira e
cores tipadas com tag explícita; fundos por fill, bordas por stroke e opacity
continuam separados. MemoryResolver e FileResolver com raiz canônica
implementam busca limitada de assets, templates e fontes.
FontManager::register_from registra uma fonte lógica exata sob o limite de
bytes do chamador e nunca varre as fontes do host.
A ordem explícita de fallback faz parte do fingerprint. SVG e HTML incorporam
as famílias realmente escolhidas nos glyph runs resolvidos, inclusive células
de tabela.
A cascata completa é defaults → theme → template → style expandido de
component/nome/inline → regras condicionais de dados ordenadas → SetStyle
runtime transacional → ExportStyleOverride. Style runtime muda antes da
medição. A layer de export expõe somente fill, stroke, opacity e cor de texto,
portanto não invalida geometria resolvida. Layer, z-index e ordem da origem
ordenam pintura independentemente da colisão por geometria.
Metadados raster e SVG são resolvidos antes do export. contain e o ramo de
redução de scale_down preservam aspecto em microunidades fixed-point; fill,
none intrínseco, crop, cover focal e EXIF opcional geram retângulos imutáveis de
origem, destino e clip. Preflight calcula DPI raster efetivo após o transform.
SVG/HTML incorporam SVG; PDF/raster registram sua rasterização ainda não
suportada como perda explícita de fidelidade.
A política de colisão herda na ordem explícita documento → página → região →
grupo → elemento. O YAML aceita collision: false, e o reflow consulta o bound
medido selecionado: layout, visual ou intrínseco.
Transforms fixed-point aceitam translação, rotação em graus inteiros, escala, flip/mirror e origins explícitas. Eles compõem através de grupos, e PDF, SVG, PNG/JPEG e HTML consomem a mesma matriz resolvida.
Elementos de texto declaram layout por text_options. Overflow aceita wrap,
shrink, ellipsis, clip, expand e error, com max_lines limitado,
min_font_size absoluto e line_height fixed-point. Medição e expansão
ocorrem antes da colisão; clipping é geometria resolvida; SVG e HTML renderizam
os runs moldados/truncados. writing_mode: vertical implementa colunas de cima
para baixo que avançam da direita para a esquerda em PDF, SVG, PNG/JPEG e HTML.
Emoji colorido continua uma perda explícita até ser implementado.
Geometria declarativa também atravessa YAML e IR sem alteração. constraints
carrega mínimo, preferido, máximo e aspect ratio largura/altura fixed-point;
align_x e align_y escolhem início, centro ou fim no container ativo.
Anchors apontam para bordas de elementos anteriores ou guides nomeadas com
guide:nome[+offset]. Coordenadas, ranges e ratios contraditórios falham
explicitamente. Patches move/resize substituem a intenção posicional anterior.
Containers de flow vertical e horizontal aceitam start, center, end,
space_between, space_around e space_evenly. Distribuição diferente de
start exige tamanho primário explícito, preferido ou derivado de aspect;
auto-medição ambígua e overflow falham antes da colisão.
O planejamento de flow distribuído conta os filhos visíveis em duas passagens
limitadas, sem alocar uma lista temporária de referências e preservando o mesmo
espaçamento.
O fingerprint ordena referências emprestadas aos nomes de assets, evitando
strings clonadas durante a resolução determinística.
exclusions nomeadas no nível superior definem retângulos relativos à página
que não são pintados e devem ficar dentro do trim box. Elas repetem dentro do
orçamento global de geometria e inicializam o índice espacial de cada página
física antes de posicionar elementos. Os campos opcionais group e
collides_with usam o mesmo contrato simétrico de colisão dos elementos,
enquanto a política push/error/next-page/shrink do candidato continua
responsável pelo reflow limitado. Inspeção, máscaras de colisão e consultas de
regiões livres mantêm a exclusão resolvida; exporters não recebem node para
pintá-la.
Páginas de documento podem declarar layers master, first, continuation e
last, cada uma dividida em bandas background, header e footer sem
colisão. Elementos master repetem em toda página física; uma layer de papel é
escolhida depois da paginação limitada do corpo; e o texto {page}/{pages}
só é resolvido quando o total final é conhecido. Componentes, estilos, binding,
patches, inspeção e todos os exporters da cena respeitam o mesmo contrato.
Elementos resolvidos mantêm um flag collidable para que overlays não criem
colisões falsas, consumam regiões livres ou alterem a paginação.
As camadas de página percorrem os elementos ativos de forma lazy por página
física, sem alocar uma lista temporária de referências.
Streams Dataset reiniciáveis param na amostra limitada da coluna auto sem
varrer o restante. Tabelas resolvem larguras fixed, auto por amostra e flex
ponderada; paginam linhas fixas ou medidas por callback com capacidade correta
do header inicial/repetido; mantêm limites de grupo e estilos condicionais; e
emitem totais integer/decimal/currency verificados somente na página final.
Limites de linha, field, célula, expressão, amostra e página falham fechados.
O YAML estrito agora expõe esse contrato diretamente: um elemento
type: table deve declarar suas colunas e um binding para array. Agrupamento,
totais, estilos condicionais, repetição do header e tamanho de linha permanecem
tipados em TableIr; cada linha vinculada deve ser object. Limites específicos
do template para linhas, fields e células só podem restringir os limites de
recursos globais do compiler.
O layout agora converte cada página limitada da tabela em um
ResolvedTableFragment imutável numa página física da cena. Colunas exatas,
headers repetidos, retângulos de linha/célula, estilos de dados, continuidade de
grupo, totais e texto moldado são fixados antes do export. Continuações usam os
limites globais normais de páginas e colisão; exporters não medem nem repaginam.
PDF editável/flattened/híbrido, SVG, PNG/JPEG e HTML semântico/fixo agora renderizam esses fragments resolvidos diretamente. O uso de fontes no PDF inclui cada run de célula, SVG e HTML incluem as fontes dos estilos de dados, e o raster contorna os mesmos glyphs moldados. O preflight valida estrutura da tabela, limites das células, diagnósticos de texto e requisitos de fontes incorporadas antes do export.
Os outputs implementados são PDF editável/flattened/híbrido, SVG, PNG, JPEG,
HTML semântico/fixo, CSV streaming e máscaras PNG/PDF/SVG/JSON. Modos e nodes
preparados falham explicitamente ou entram em ExportLossReport.
Todo formato de documento escreve em um writer do chamador e também oferece bytes limitados em memória; CSV de dataset transmite linhas pelas mesmas duas interfaces. DPI se aplica somente a PNG/JPEG e qualidade somente a JPEG. PNG preserva transparência, enquanto JPEG registra flattening de alpha de style ou imagem antes do output strict. HTML fixo não anuncia capability semântica. PDF emite metadados determinísticos de título, creator e producer; PDF editável embute subsets exatos de glyphs e mapas Unicode. PDF Hybrid pinta outlines determinísticos e acrescenta texto Unicode invisível e subsetado nas coordenadas resolvidas dos glyphs para busca, seleção e extração. Links, bookmarks, acessibilidade tagged, PDF/A, WebP, XLSX, ZPL e ESC/POS permanecem contratos preparados explícitos.
A validação tem etapas explícitas de schema, dados tipados, layout resolvido e preflight consciente do exporter. Warnings limitados são first-class; strict os rejeita e truncamento do report falha fechado. Preflight detecta gaps de binding, asset, glyph, colisão, overflow, DPI efetivo, vector/CMYK/alpha JPEG, font incorporada para PDF editável/híbrido e acessibilidade solicitada.
Fingerprints determinísticos enquadram versões de schema e engine,
template/dados/patches canônicos, digests dos assets referenciados e das fonts
registradas. Campos JSON canônicos usam uma passagem de dimensionamento seguida
de hashing SHA-256 direto sob o budget agregado max_output_bytes, preservando
o framing V1 sem reter um buffer JSON completo.
LayoutEngine::resolve_cached resolve somente em miss do
SceneCache limitado, retorna cenas imutáveis compartilhadas para render-many
e rejeita versões antigas do engine.
O batch ordenado completo de patches tem limite global; remove/replace rejeitam
um subtree alvo que contenha qualquer descendente locked.
Trabalho sobre input hostil tem limites explícitos. O binding compartilha um único orçamento de elementos entre raízes, descendentes e expansão de repeats, com cancelamento/progresso cooperativo nas fronteiras de elemento. O layout tem um orçamento total de comparações espaciais além do reflow limitado. Leituras de filesystem sob raiz canônica rejeitam traversal e links de escape, abrem sem seguir symlink/reparse point final substituído, respeitam o limite de bytes e revalidam o sandbox ao redor da leitura. O cancelamento de export ocorre antes de output visível pelo chamador.
Os gates de confiabilidade incluem snapshots exatos do SVG visual e da mask de colisão, properties de geometria fixed-point e fuzz targets separados para o pipeline YAML/bind/layout limitado, Unicode arbitrário e texto grande demais, assets raster corrompidos, tamanhos absurdos/overlaps/anchors circulares e grafos de include malformados, circulares ou profundos demais. Input inválido pode falhar com erro tipado, mas não pode causar panic, loop infinito ou alocação sem limite explícito.
Debug permanece uma layer derivada e somente leitura. DebugOverlay fornece
grids limitados de 1/5/10/20 pontos, rulers, coordenadas, IDs, bounds distintos,
anchors, regions resolvidas, geometria safe/collision, exclusões e crosshairs
sem mudar layout ou ordem de pintura. Masks collision/layout/visual/combined
derivam retângulos ocupados e livres por view e exportam PNG, PDF, SVG ou JSON
estável occupied/free/collisions/overflow. inspect e explain preservam trace
estruturado de x/y/width/height de origem, anchors, region, medição, policy de
colisão, página/reflow e provenance.
JSON, SVG e PDF da mask primeiro contam sob max_output_bytes sem reter o
output, rejeitam resultado excessivo antes de tocar no destino e então
serializam direto no writer do chamador. PDF emite objetos independentes, um
stream de comandos fixed-point de tamanho exato e seu xref sem buffer de página
ou arquivo completo. collision_mask_json_4m mede um output exato de 4.188.826
bytes; collision_mask_pdf_100k mede 100.000 retângulos e um PDF exato de
1.800.626 bytes com checkpoints RSS idle, pico e retido.
O macrobenchmark a4_report_export_matrix mede o pipeline A4 mantido de duas
páginas como uma operação limitada: decoding de YAML e dados tipados, patch em
runtime, medição/layout/colisão/reflow, preflight e nove outputs em streaming.
Ele cobre PDF editável, flattened e híbrido; SVG; HTML semântico e fixo; PNG;
JPEG com losses best-effort explícitos; e CSV do dataset. Três amostras isoladas
do commit limpo no Apple M1 mediram 70,56 ms p50, 71,34 ms p95, MAD de 0,22 ms
e 10,64 MiB de RSS pico.
O core determinístico não depende de IA. appcore-filemaker-ai é um bridge
opcional de 20 tools sobre appcore-ai; appcore-filemaker-cli é o adaptador
de processo limitado. Exemplos e evidências estão na branch beta do Runtime.
Export e preflight rejeitam independentemente cenas resolvidas públicas antigas
ou malformadas e aplicam budgets de páginas, elementos, paths, linhas, texto e
coordenadas antes de escrever. Overlay diagnóstico, mask de colisão/JSON e
regiões livres também consomem limites explícitos de comparações e geometria
retida. IDs validados preservam o invariante do construtor ao desserializar.
Exports controlados observam cancelamento e reportam progresso dentro dos loops
reais de elementos dos renderers, antes de escrever o output preparado ao
chamador.
O pipeline de fonts explícitas usa harfrust, mantido pelo projeto HarfBuzz,
para shaping e skrifa, do Google Fonts, para validação, métricas e outlines;
ele não descobre fonts do sistema operacional.
Uma font válida sem capital height em OS/2 usa ascent como policy explícita e
determinística de CapHeight do PDF; advances ausentes falham.
Os exemplos Rust executáveis mantêm o documento nos arquivos separados
basic.yml
e intermediate.yml.
Os dados tipados ficam em arquivos JSON correspondentes e separados. O runner
básico gera um SVG completo de uma página com texto associado, desenhos
semânticos, sparkline e tabela estilizada. O intermediário gera um relatório
confidencial de exatamente duas páginas, com numeração, watermark repetido,
gráficos vetoriais, tabela paginada, preflight estrito, PDF editável, HTML fixo
e previews SVG por página. Ambos registram explicitamente a Noto Sans sob OFL
incluída, sem depender de fontes do host. O código Rust não embute YAML nem JSON.
Documentação mantida pelo crate: guia, exemplo básico e exemplo intermediário.