Skip to contents

blockr.io (development version)

Features

  • A file format registry. register_format() teaches blockr.io a file format at load time and register_container() a container (a location holding several tables: a directory, a zip, a workbook read sheet-wise); the registry is consulted when a block builds its read expression and never appears in the code it builds. Containers produce a bare named list of data frames – no class; whatever the list should become is the consuming block’s wrap. Four container entries ship in-box (directory, zip, excel sheets, rds/rdata lists), the bespoke csv/excel/arrow builders are named entries, and rio is one fallback entry with lowest precedence, so existing boards read exactly as they did. file_extensions() returns named entries plus the fallback’s claims and grows with registration (upload accept lists included). Same-key registrations from two namespaces error at first lookup naming both; same-namespace re-registration replaces, so load_all() is safe.

  • Options passed at a container read are uniform member options: the directory and zip entries forward them into every member’s format entry, which picks the parameters it understands – sep = ";" reaches every csv in a folder and the parquet next to them ignores it.

  • An entry declares what it accepts. register_format(options = ...) takes a named list of opt_choice() / opt_text() / opt_number() / opt_flag() specs, and format_options() / source_options() answer “what can be set when reading this?” for a file or a whole container (a folder of CSVs offers the csv options; a folder of parquet offers none). Blocks generate their settings fields from the answer with format_options_ui() / format_options_values() instead of hardcoding per-format panels, so a format registered by another package gets its options offered – fields, gear, read-back – without any block changing. The read block’s csv and excel panels and its eleven per-field observers are now one declaration and one generic observer; a side effect is that an external write to the delimiter lands, which the hand-maintained fan-out never did (it pushed a selectize with updateTextInput).

  • gear_band_ui() exports the gear-and-band settings affordance this package’s blocks use, so sibling packages mount the same one.

Bug fixes

  • The read block badges a directory as “Directory” and reports it on the block (“a directory holds several tables and needs a multi-table block”) instead of badging it as a readable “File” and throwing out of the expression build, which left a stale preview and a log-only error. Any other build failure (an unregistered extension, a registry collision) rides in the expression the same way.

  • No options, no gear: the read block’s gear only shows when the settings band has fields for the detected format (csv, excel, or several files for the combine section) – on any other format it opened an empty band.

  • The upload dialog’s accept list derives from file_extensions() rather than the rio list directly, so a registered format is uploadable.

Internal

Features

  • resolve_data_dir() is exported. Resolving a path against the board’s data directory was written out longhand in every block that takes one – same regex, four copies – which is how a block ends up resolving differently from the path widget next to it, reading one file while showing another.

Bug fixes

  • The write block’s directory field fills itself in on a late-mounted panel too. Its push ran once = TRUE, so it could not even be re-sent, and it duplicated the module’s prefix strip (empty-remainder flaw included). It now hands value to path_input_server() like the read block.

  • A path that is the board’s data directory is no longer stripped to the empty string for display. The field went blank a moment after the value landed – placeholder back, prefix span hidden, so the block read as unconfigured while it was reading its data perfectly well. The strip is also silent now: it is the field being normalised, not somebody choosing a file, and the change event it fired reported the shortened path back as a commit.

  • The path field comes up filled in, and works, inside a dock panel that was not open when the board loaded. Its script arrives with the panel, so the value pushed at boot reached a Shiny with no handler for the message and was dropped; and the only hook that wired the field’s autocomplete was an output event that had already fired. The widget now announces itself when Shiny binds it, and path_input_server() gained a value argument so the module answers – callers no longer push at the field themselves.

  • The read block no longer treats the path field’s bind-time echo as a user choosing a file. Inside a dock the field enters the DOM when its panel is first shown and immediately reports the path the block had written into it, which relabelled an uploaded file’s source as a plain path.

  • write_block’s exported/eval’d expression now sets expr_type = "bquoted" and marks its input slot with the .() marker, so blockr.core substitutes the actual input name on eval and export. Exported code now reads e.g. readr::write_csv(x = sales, ...) directly instead of being wrapped in with(list(.arg1 = sales), ...). The imperative save/download handlers keep bare symbols, since their slot values are already bound in the eval env.

  • write_expr() now fills empty (positional) slot display names with data_1, data_2, … instead of using them verbatim. Variadic links added positionally (the blockr.ui / blockr.dock link menus) arrive with "" names, which produced colliding .csv entries inside multi-input ZIP downloads (each write clobbering the last) and empty Excel sheet names.

Design-system alignment

  • The gear button on the read, write, and download blocks now expands a full-width, in-flow settings band (the blockr design-system pattern, shared with blockr.viz and blockr.ggplot) instead of a floating popover. The band is a persistent panel: it stays open while you work and only the gear closes it. The settings-band CSS/JS is vendored verbatim from blockr.viz (the canonical source).
  • All block styling moved out of R-generated <style> tags into inst/assets/css/io-blocks.css and is tokenized against the design system: colors, radii, control heights, and transitions are var(--blockr-*, <canonical fallback>), so blocks pick up host themes while rendering canonically standalone.
  • Checkboxes are restyled to the design-system .blockr-checkbox recipe (16px box, primary fill, inline SVG check) while keeping their Shiny bindings; one recipe covers both Bootstrap 3 and Bootstrap 5 markup.
  • The required-but-empty amber cue on path inputs uses the canonical .blockr-field--required-empty class; the old .blockr-path-required-empty name remains as a CSS alias for one release.
  • In-block h4 titles are gone: the block name is the title; section headings render as micro-labels (.io-section-label / .blockr-settings__title).

Path input: commit on Enter

  • Path inputs now follow the blockr design-system text-commit convention: typing only drives the autocomplete dropdown; the value is committed (and the file read / directory applied) on Enter, blur, or a dropdown selection. While the typed text is not yet applied, the field shows an “Enter” chip that collapses to a faded check mark on commit. This removes per-keystroke pipeline recomputes (the main source of autocomplete lag) and mid-typing file reads.
  • Autocomplete responses are sequence-guarded, so a slow response for an older query can no longer overwrite the dropdown for a newer one.
  • Directory listings use a single vectorized file.info() call, rank prefix matches before substring matches (directories first), and show a “Showing 50 of N” footer when the listing is capped.
  • The listing endpoint now honors the deployment file-access policy (blockr.verify_read_path / blockr.verify_write_path): directories outside the allowed roots are no longer enumerable via autocomplete.
  • Open dropdowns follow their input on scroll/resize, keyboard navigation keeps the active item in view, and dropdowns of removed blocks are cleaned up.
  • path_input_ui() gains a placeholder argument; path_input_server() gains a policy argument. new_data_dir_option() shares the listing implementation instead of duplicating it.

Write block

  • The output directory is created at write time (inside the generated write expression) instead of while the path is typed — typing a path no longer creates partial directories. The path badge shows “New directory (created on save)” for not-yet-existing targets.
  • Manual mode is one-shot: each “Save to Server” click writes exactly once, imperatively. Upstream data changes no longer silently rewrite the file. The block expression is a pure passthrough of the first input except in auto-write mode, where it carries the write so exported code reproduces it.
  • The reported “Saved to …” path is now always the written path (single filename computation; previously two Sys.time() calls could disagree).
  • Fixed the “File Configuration” header rendering beside (instead of above) the filename/format fields in wide panels: the header wrapper is a grid item under the responsive form grid and now explicitly spans the full row.
  • Auto-write with an empty filename writes a fixed data.{ext} file, overwritten on each change, instead of creating a new timestamped file per upstream change. Manual saves and downloads keep timestamped names.

blockr.io 0.1.0

CRAN release: 2026-01-07

Initial CRAN release.

Features

Data Import Block

  • new_read_block(): Read data from various file formats
    • CSV, TSV, and delimited files (via readr)
    • Excel files (via readxl)
    • Arrow formats: Parquet, Feather, IPC (via arrow)
    • Other formats via rio package
    • URL support for remote files
    • Multi-file selection with combine options (rbind, cbind)
    • Advanced CSV options (delimiter, encoding, skip rows, etc.)

Data Export Block

  • new_write_block(): Write data to various file formats
    • CSV export (via readr)
    • Excel export with multiple sheets (via writexl)
    • Parquet and Feather export (via arrow)
    • Directory browser for output location
    • Auto-timestamped filenames
    • Multiple dataset export (zipped for CSV/Arrow)

Documentation

  • Full documentation for all exported functions
  • Package website with examples