npm package: @josieyjj/flutter-bridge
Description: Service for communication between webview and Flutter host.
Latest version: 0.1.2

# @josieyjj/flutter-bridge

[![NPM Version](https://img.shields.io/npm/v/@josieyjj/flutter-bridge.svg)](https://www.npmjs.com/package/@josieyjj/flutter-bridge)
[![License](https://img.shields.io/npm/l/@josieyjj/flutter-bridge.svg)](https://opensource.org/licenses/MIT)

A lightweight, promise-based bridge to facilitate communication between a Vue.js web application (MiniApp) and its Flutter native host using `dsbridge`.

This package provides a singleton service that simplifies calling native functions from JavaScript and handles the initialization handshake, ensuring that communication only happens when the bridge is ready.

## Features

- **Singleton Service**: A single, shared instance (`flutterService`) ensures state consistency across your entire application.
- **Promise-based API**: All calls to the native side are asynchronous and return Promises for easy handling with `async/await`.
- **Type-Safe**: Written in TypeScript with exported types for all data payloads (`UserData`, `NfcCardData`, etc.).
- **Graceful Fallback**: Works safely in a standard web browser (where `dsbridge` is not present) for easier development and testing.
- **Idempotent Initialization**: The `init()` method can be called multiple times without side effects.

---

## Prerequisites

This package requires the native Flutter application to have the dsbridge-flutter library (or a similar implementation) integrated into its WebView. The native side **must** expose the required methods as specified in the Native Side Implementation section.

## Installation

```bash
# Using pnpm (recommended for this monorepo)
pnpm add @josieyjj/flutter-bridge

# Using npm
npm install @josieyjj/flutter-bridge

# Using yarn
yarn add @josieyjj/flutter-bridge
```

## Quick Start

It's recommended to initialize the bridge in your root component (`App.vue`) to ensure it's ready before any pages try to use it.

**In `App.vue`:**

```vue
<script setup lang="ts">
import { flutterService, type InitPayload } from '@josieyjj/flutter-bridge';
import { onMounted, ref } from 'vue';
import { useAppCommonStroe } from "@/stores/appCommonStore";

const isReady = ref(false);
const appStore = useAppCommonStroe();

onMounted(async () => {
  const initPayload: InitPayload | null = await flutterService.init();

  if (initPayload?.isReady) {
    console.log('Flutter bridge is ready!');
    isReady.value = true;

    // If user data is returned on init, store it
    if (initPayload.userData) {
      appStore.userData = initPayload.userData;
    }
  } else {
    console.warn('Running in a non-native environment or initialization failed.');
    // Handle fallback for web-only development if needed
    isReady.value = true; // Or false, depending on desired behavior
  }
});
</script>

<template>
  <router-view v-if="isReady" />
</template>
```

**In any other component:**

```vue
<script setup lang="ts">
import { flutterService, type NfcCardData } from '@josieyjj/flutter-bridge';

async function handleScanClick() {
  const cardData: NfcCardData | null = await flutterService.openNfcCardScan();
  if (cardData) {
    alert(`Scanned card with ID: ${cardData.tagId}`);
  } else {
    alert('NFC scan was cancelled or failed.');
  }
}
</script>
```

## API Reference

All methods are accessed via the imported `flutterService` singleton instance.

### `flutterService.init(): Promise<InitPayload | null>`

Initializes the connection with the Flutter host. It performs the initial handshake to ensure the bridge is ready.
- **Returns**: A `Promise` that resolves to an `InitPayload` object on success, or `null` on failure or in a non-native environment.

### `flutterService.getUserData(): Promise<UserData | null>`

Requests the current user's data from the Flutter host.
- **Returns**: A `Promise` that resolves to a `UserData` object or `null`.

### `flutterService.openNfcCardScan(): Promise<NfcCardData | null>`

Requests the Flutter host to open the native NFC card scanning interface.
- **Returns**: A `Promise` that resolves to an `NfcCardData` object if a card is successfully scanned, or `null` if the operation is cancelled or fails.

---

## Native Side Implementation

The Flutter application's `DWebView` controller must register the following asynchronous handlers.

1.  **`isFlutterPluginReady()`**
    - **Description**: Called by the web app during `init()` to check for readiness.
    - **Should Return**: An `InitPayload` object.
      - On success: `{ "isReady": true, "userData": { ... } }`
      - On failure: `{ "isReady": false, "userData": null }`

2.  **`getUserData()`**
    - **Description**: Called to get user information on demand.
    - **Should Return**: A `UserData` object or `null`.

3.  **`openNfcCardScan()`**
    - **Description**: Called to trigger the native NFC scanning UI.
    - **Should Return**: An `NfcCardData` object on a successful scan, or `null` if cancelled.

## License

MIT