Skip to content

feat(ios): runtime .pulsar bundle loader + SwiftPM plugin (2/6) - #203

Merged
piaskowyk merged 3 commits into
mainfrom
feat/preset-bundles-ios
Aug 11, 2026
Merged

feat(ios): runtime .pulsar bundle loader + SwiftPM plugin (2/6)#203
piaskowyk merged 3 commits into
mainfrom
feat/preset-bundles-ios

Conversation

@piaskowyk

Copy link
Copy Markdown
Member

Stack 2/6 — base: feat/preset-bundles-format.

What

Runtime bundle loading in the standalone iOS SDK (PulsarHaptics, the pod RN + Flutter link against).

  • Bundle/PulsarUnzip.swift — minimal STORE+DEFLATE zip reader over the Compression framework (no new dependency).
  • Bundle/PulsarBundle.swift — Codable manifest; PresetHandle (lazy parse, synced audio via parsePatternWithSound, animation bytes exposed for the app to render); LoadedBundle (untyped string-keyed surface for the RN/Flutter bridges); typed PulsarBundle<P> / BundleDescriptor<P> / BundleResolver.
  • Bundle/BundleLoader.swiftPulsar.loadBundle(data:/path:) + typed loadBundle(_:strict:). Haptics JSON decodes straight into the existing PatternData; audio extracted to caches for Core Haptics.
  • pulsar-gen-swift host tool + PulsarGenPlugin build-tool plugin — regenerate the typed accessor on every build, no Node in the sandbox.
  • BundleTests (Swift Testing): unzip + load + typed-view + schema rejection.

The loaded bundle owns its handles, so the compiled preset registry is untouched.

Verification

⚠️ Native/UIKit code is not compiled in the authoring environment — please run xcodebuild test on a simulator (the design reuses PatternData/Player/PatternComposer and existing test patterns).

Foundation for custom preset bundles. Defines the .pulsar format (ZIP +
manifest.json), a JSON schema, and pulsar-gen: a zero-dependency Node/TS CLI
that reads a .pulsar and emits typed accessors for swift/kotlin/dart and an
RN JSON sidecar (keyof-inference, nano-icons style). Includes a fixture bundle,
golden outputs, and a node:test suite (7 passing). Portable emitter core is
reusable from Studio's browser exporter.
Adds runtime bundle loading to the standalone iOS SDK (PulsarHaptics), the
artifact RN + Flutter link against:

- Bundle/PulsarUnzip.swift: minimal STORE+DEFLATE zip reader over the
  Compression framework (no new dependency).
- Bundle/PulsarBundle.swift: Codable manifest, PresetHandle (lazy parse,
  synced audio via parsePatternWithSound, animation bytes for the app to
  render), LoadedBundle (untyped string-keyed surface for the RN/Flutter
  bridges), and the typed PulsarBundle<P>/BundleDescriptor<P>/BundleResolver.
- Bundle/BundleLoader.swift: Pulsar.loadBundle(data:/path:) + typed
  loadBundle(_:strict:); haptics JSON decodes straight into PatternData;
  audio extracted to caches for Core Haptics.
- pulsar-gen-swift host tool + PulsarGenPlugin build-tool plugin: regenerate
  the typed accessor on every build, no Node/network in the sandbox.
- BundleTests: unzip + load + typed-view + schema-rejection (Swift Testing).

The loaded bundle owns its handles, so no change to the compiled preset
registry. Note: native/plugin code is not compiled in this environment
(iOS/UIKit); verify via xcodebuild on a simulator.
Base automatically changed from feat/preset-bundles-format to main August 11, 2026 15:38
@piaskowyk
piaskowyk merged commit 9a2674e into main Aug 11, 2026
1 check failed
@piaskowyk
piaskowyk deleted the feat/preset-bundles-ios branch August 11, 2026 15:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant