npm package: @juuno-sdk/app-sdk
Description: Juuno App SDK - Complete toolkit for building external Juuno apps
Author: Juuno
Latest version: 1.0.2

# @juuno-sdk/app-sdk

> Complete toolkit for building external Juuno apps

## Overview

`@juuno-sdk/app-sdk` is the all-in-one package for developing external Juuno apps. It bundles everything you need - config UI components, player utilities, icons, styles, and more - into a single, easy-to-use SDK.

## Installation

```bash
npm install @juuno-sdk/app-sdk
```

### Peer Dependencies

This package requires:

```json
{
  "peerDependencies": {
    "vue": "^3.5.22"
  }
}
```

## What's Included

- **Config UI Framework**: Components and utilities for building app configuration interfaces
- **Player Utilities**: Components and helpers for rendering app content
- **UI Components**: Buttons, modals, inputs, color pickers, and more
- **Icons**: Common icon components (SvgAdd, SvgClose, SvgDelete, etc.)
- **Styles**: Pre-bundled CSS for consistent styling
- **Types**: TypeScript types for all APIs
- **Utilities**: Helper functions (createLogger, cloneDeep, etc.)

## Usage

### Basic App Structure

```typescript
// src/player/AppSlide.vue
<script setup lang="ts">
import {
  type AppSlideProps,
  createLogger
} from '@juuno-sdk/app-sdk';

const Logger = createLogger('MyApp');
const props = defineProps<AppSlideProps>();
</script>

<template>
  <div class="my-app">
    <!-- Your app content -->
  </div>
</template>
```

### Config UI Example

```typescript
// src/config/AppConfig.vue
<script setup lang="ts">
import {
  useAppConfigContext,
  ColorPickerInput,
  CustomSelect,
  type SceneMeta
} from '@juuno-sdk/app-sdk';

interface MyAppMeta extends SceneMeta {
  backgroundColor: string;
  fontSize: number;
}

const appConfigContext = useAppConfigContext<MyAppMeta>();
const { sceneMeta } = appConfigContext;

appConfigContext.setupScene({
  backgroundColor: '#ffffff',
  fontSize: 16,
});
</script>

<template>
  <div class="config">
    <ColorPickerInput
      v-model="sceneMeta.backgroundColor"
      label="Background Color"
    />
    <CustomSelect
      v-model="sceneMeta.fontSize"
      :options="[12, 14, 16, 18, 20]"
      label="Font Size"
    />
  </div>
</template>
```

### Importing Styles

The SDK includes pre-bundled styles. Import them in your app:

```typescript
// In your main entry or component
import '@juuno-sdk/app-sdk/styles.css';
```

## Available Exports

### Config UI

- `useAppConfigContext<T>()` - Access app config context
- `provideAppConfigContext()` - Provide config context
- `AppConfigContainer` - Container for config UI
- `SelectTextPosition` - Text position selector
- `WysiwygEditor` - WYSIWYG editor component
- `useDirtyState()` - Track unsaved changes

### Player Utilities

- All exports from `@juuno/apps-player-common`
- All exports from `@juuno/apps-core`
- All exports from `@juuno/apps-slideshow-common`

### UI Components

- `ColorPickerInput` - Color picker component
- `CustomScrollbar` - Custom scrollbar component
- `ScaleChildren` - Scale children to fit container
- `InputSearch` - Search input component
- `ButtonSquare` - Square button component
- `CustomSelect` - Custom select dropdown
- `CustomSelectObject` - Select dropdown for objects
- `FModal` - Modal component
- `useModalContext()` - Modal context hook
- `useModalInstanceContext()` - Modal instance hook
- `LoadingSpinner` - Loading spinner component
- `FPagination` - Pagination component

### Icons

- `SvgAdd` - Add icon
- `SvgClose` - Close icon
- `SvgDelete` - Delete icon
- `SvgUpload` - Upload icon

### Types

- `Scene` - Scene type
- `SceneMeta` - Scene metadata type
- `ZoneScene` - Zone scene type
- `AppSlideProps` - App slide props type
- `MediaAsset` - Media asset type
- `ScreenOrientationEnum` - Screen orientation enum
- `App` - App type
- `Workspace` - Workspace type

### Utilities

- `createLogger(name)` - Create a logger instance
- `cloneDeep(obj)` - Deep clone an object
- `isEmpty(obj)` - Check if object is empty
- `isEqual(a, b)` - Deep equality check
- `debounce(fn, delay)` - Debounce a function

## Build Configuration

External apps should externalize the SDK and Vue:

```typescript
// vite.config.ts
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import { resolve } from 'path';

export default defineConfig({
  plugins: [vue()],
  server: {
    port: 5002,
    cors: true,
  },
  build: {
    lib: {
      entry: resolve(__dirname, 'src/index.ts'),
      formats: ['es'],
      fileName: 'index',
    },
    rollupOptions: {
      external: ['vue', '@juuno-sdk/app-sdk'],
    },
  },
  resolve: {
    alias: {
      '@': resolve(__dirname, 'src'),
    },
  },
});
```

## What's NOT Included

For external apps, the following features are not available:

- ❌ **Media Library**: External apps should use URLs for media
- ❌ **Font Management**: Use Google Fonts or custom web fonts
- ❌ **i18n System**: Implement your own or use vue-i18n
- ❌ **GraphQL/Backend Integration**: External apps are self-contained

## Getting Started

### Example App

See [`external/app-sdk-example`](../app-sdk-example) for a complete working example that demonstrates:

- ✅ App structure and component organization
- ✅ Configuration UI with SDK components
- ✅ Player component implementation
- ✅ TypeScript integration
- ✅ CSS import and styling

### Creating a New App

Use `create-juuno-app` to scaffold a new external app:

```bash
npx create-juuno-app my-custom-app
cd my-custom-app
npm install
npm run dev
```

### TypeScript Configuration

External apps need type stubs for SVG and GraphQL files that may be imported from SDK dependencies:

```typescript
// types/svg.d.ts
declare module '*.svg?component' {
  import { DefineComponent } from 'vue';
  const component: DefineComponent<{}, {}, any>;
  export default component;
}

declare module '*.svg?skipsvgo' {
  import { Component } from 'vue';
  const src: string & Component;
  export default src;
}

// types/graphql.d.ts
declare module '*.graphql' {
  import { DocumentNode } from 'graphql';
  const document: DocumentNode;
  export default document;
}
```

Then configure `tsconfig.json` to exclude internal packages and skip lib checking:

```json
{
  "extends": "@vue/tsconfig/tsconfig.dom.json",
  "include": ["src/**/*", "src/**/*.vue", "types/**/*"],
  "exclude": [
    "node_modules/@juuno/core/**/*",
    "node_modules/@juuno/icons/**/*"
  ],
  "compilerOptions": {
    "skipLibCheck": true,
    "skipDefaultLibCheck": true
  }
}
```

## Related Packages

- **@juuno-sdk/app-simulator**: Development tool for testing external apps
- **@juuno-sdk/app-sdk-example**: Example external app demonstrating SDK usage

## License

MIT