parent
dc7de9d8f9
commit
0365673c41
83
build.ts
83
build.ts
|
@ -13,28 +13,25 @@ import { bundle as plugOsBundle } from "./plugos/bin/plugos-bundle.ts";
|
|||
import * as flags from "https://deno.land/std@0.165.0/flags/mod.ts";
|
||||
|
||||
// @ts-ignore trust me
|
||||
const esbuild: typeof esbuildWasm = Deno.run === undefined
|
||||
export const esbuild: typeof esbuildWasm = Deno.run === undefined
|
||||
? esbuildWasm
|
||||
: esbuildNative;
|
||||
|
||||
async function prepareAssets(dist: string) {
|
||||
await copy("web/fonts", `${dist}/web`, { overwrite: true });
|
||||
await copy("web/index.html", `${dist}/web/index.html`, {
|
||||
export async function prepareAssets(dist: string) {
|
||||
await copy("web/fonts", `${dist}`, { overwrite: true });
|
||||
await copy("web/index.html", `${dist}/index.html`, {
|
||||
overwrite: true,
|
||||
});
|
||||
await copy("web/auth.html", `${dist}/web/auth.html`, {
|
||||
await copy("web/auth.html", `${dist}/auth.html`, {
|
||||
overwrite: true,
|
||||
});
|
||||
await copy("web/images/favicon.png", `${dist}/web/favicon.png`, {
|
||||
await copy("web/images/favicon.png", `${dist}/favicon.png`, {
|
||||
overwrite: true,
|
||||
});
|
||||
await copy("web/images/logo.png", `${dist}/web/logo.png`, {
|
||||
await copy("web/images/logo.png", `${dist}/logo.png`, {
|
||||
overwrite: true,
|
||||
});
|
||||
await copy("web/manifest.json", `${dist}/web/manifest.json`, {
|
||||
overwrite: true,
|
||||
});
|
||||
await copy("server/SETTINGS_template.md", `${dist}/SETTINGS_template.md`, {
|
||||
await copy("web/manifest.json", `${dist}/manifest.json`, {
|
||||
overwrite: true,
|
||||
});
|
||||
const compiler = sass(
|
||||
|
@ -44,53 +41,61 @@ async function prepareAssets(dist: string) {
|
|||
},
|
||||
);
|
||||
await Deno.writeTextFile(
|
||||
`${dist}/web/main.css`,
|
||||
`${dist}/main.css`,
|
||||
compiler.to_string("expanded") as string,
|
||||
);
|
||||
const globalManifest = await plugOsBundle("./plugs/global.plug.yaml");
|
||||
await Deno.writeTextFile(
|
||||
`${dist}/web/global.plug.json`,
|
||||
`${dist}/global.plug.json`,
|
||||
JSON.stringify(globalManifest, null, 2),
|
||||
);
|
||||
|
||||
// HACK: Patch the JS by removing an invalid regex
|
||||
let bundleJs = await Deno.readTextFile(`${dist}/web/client.js`);
|
||||
let bundleJs = await Deno.readTextFile(`${dist}/client.js`);
|
||||
bundleJs = patchDenoLibJS(bundleJs);
|
||||
await Deno.writeTextFile(`${dist}/web/client.js`, bundleJs);
|
||||
|
||||
await bundleFolder(dist, "dist/asset_bundle.json");
|
||||
await Deno.writeTextFile(`${dist}/client.js`, bundleJs);
|
||||
}
|
||||
|
||||
async function bundle(watch: boolean): Promise<void> {
|
||||
export async function bundle(
|
||||
watch: boolean,
|
||||
type: "web" | "mobile",
|
||||
distDir: string,
|
||||
): Promise<void> {
|
||||
let building = false;
|
||||
await doBuild();
|
||||
await doBuild(`${type}/boot.ts`);
|
||||
let timer;
|
||||
if (watch) {
|
||||
const watcher = Deno.watchFs(["web", "dist_bundle/_plug"]);
|
||||
const watcher = Deno.watchFs([type, "dist_bundle/_plug"]);
|
||||
for await (const _event of watcher) {
|
||||
if (timer) {
|
||||
clearTimeout(timer);
|
||||
}
|
||||
timer = setTimeout(() => {
|
||||
console.log("Change detected, rebuilding...");
|
||||
doBuild();
|
||||
doBuild(`${type}/boot.ts`);
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
async function doBuild() {
|
||||
async function doBuild(
|
||||
mainScript: string,
|
||||
) {
|
||||
if (building) {
|
||||
return;
|
||||
}
|
||||
building = true;
|
||||
if (type === "mobile") {
|
||||
await bundleFolder("dist_bundle", "dist/asset_bundle.json");
|
||||
}
|
||||
|
||||
await Promise.all([
|
||||
esbuild.build({
|
||||
entryPoints: {
|
||||
client: "web/boot.ts",
|
||||
client: mainScript,
|
||||
service_worker: "web/service_worker.ts",
|
||||
worker: "plugos/environments/sandbox_worker.ts",
|
||||
},
|
||||
outdir: "./dist_bundle/web",
|
||||
outdir: distDir,
|
||||
absWorkingDir: Deno.cwd(),
|
||||
bundle: true,
|
||||
treeShaking: true,
|
||||
|
@ -107,21 +112,27 @@ async function bundle(watch: boolean): Promise<void> {
|
|||
],
|
||||
}),
|
||||
]);
|
||||
await prepareAssets("dist_bundle");
|
||||
|
||||
await prepareAssets(distDir);
|
||||
if (type === "web") {
|
||||
await bundleFolder("dist_bundle", "dist/asset_bundle.json");
|
||||
}
|
||||
|
||||
building = false;
|
||||
console.log("Built!");
|
||||
}
|
||||
}
|
||||
|
||||
const args = flags.parse(Deno.args, {
|
||||
boolean: ["watch"],
|
||||
alias: { w: "watch" },
|
||||
default: {
|
||||
watch: false,
|
||||
},
|
||||
});
|
||||
|
||||
await bundle(args.watch);
|
||||
if (!args.watch) {
|
||||
esbuild.stop();
|
||||
if (import.meta.main) {
|
||||
const args = flags.parse(Deno.args, {
|
||||
boolean: ["watch"],
|
||||
alias: { w: "watch" },
|
||||
default: {
|
||||
watch: false,
|
||||
},
|
||||
});
|
||||
await bundle(args.watch, "web", "dist_bundle/web");
|
||||
if (!args.watch) {
|
||||
esbuild.stop();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
import { bundle, esbuild } from "./build.ts";
|
||||
import * as flags from "https://deno.land/std@0.165.0/flags/mod.ts";
|
||||
import { copy } from "https://deno.land/std@0.165.0/fs/copy.ts";
|
||||
|
||||
if (import.meta.main) {
|
||||
const args = flags.parse(Deno.args, {
|
||||
boolean: ["watch"],
|
||||
alias: { w: "watch" },
|
||||
default: {
|
||||
watch: false,
|
||||
},
|
||||
});
|
||||
await bundle(args.watch, "mobile", "mobile/dist");
|
||||
await copy("mobile/index.html", `mobile/dist/index.html`, {
|
||||
overwrite: true,
|
||||
});
|
||||
if (!args.watch) {
|
||||
esbuild.stop();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
export const SETTINGS_TEMPLATE =
|
||||
`This page contains settings for configuring SilverBullet and its plugs. Any changes outside of the yaml block will be overwritten.
|
||||
|
||||
\`\`\`yaml
|
||||
indexPage: index
|
||||
\`\`\`
|
||||
`;
|
|
@ -26,7 +26,6 @@ export class Space extends EventEmitter<SpaceEvents> {
|
|||
|
||||
public async updatePageList() {
|
||||
const newPageList = await this.fetchPageList();
|
||||
// console.log("Updating page list", newPageList);
|
||||
const deletedPages = new Set<string>(this.pageMetaCache.keys());
|
||||
newPageList.forEach((meta) => {
|
||||
const pageName = meta.name;
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
import { SETTINGS_TEMPLATE } from "./settings_template.ts";
|
||||
import { YAML } from "./deps.ts";
|
||||
import { Space } from "./spaces/space.ts";
|
||||
|
||||
export function safeRun(fn: () => Promise<void>) {
|
||||
fn().catch((e) => {
|
||||
|
@ -42,3 +44,32 @@ export function parseYamlSettings(settingsMarkdown: string): {
|
|||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
export async function ensureAndLoadSettings(space: Space) {
|
||||
try {
|
||||
await space.getPageMeta("SETTINGS");
|
||||
} catch {
|
||||
await space.writePage(
|
||||
"SETTINGS",
|
||||
SETTINGS_TEMPLATE,
|
||||
true,
|
||||
);
|
||||
}
|
||||
|
||||
const { text: settingsText } = await space.readPage("SETTINGS");
|
||||
const settings = parseYamlSettings(settingsText);
|
||||
if (!settings.indexPage) {
|
||||
settings.indexPage = "index";
|
||||
}
|
||||
|
||||
try {
|
||||
await space.getPageMeta(settings.indexPage);
|
||||
} catch {
|
||||
await space.writePage(
|
||||
settings.indexPage,
|
||||
`Welcome to your new space!`,
|
||||
);
|
||||
}
|
||||
|
||||
return settings;
|
||||
}
|
||||
|
|
|
@ -4,7 +4,9 @@
|
|||
"install": "deno install -f -A --unstable silverbullet.ts",
|
||||
"test": "deno test -A --unstable",
|
||||
"build": "deno run -A --unstable --check build_plugs.ts && deno run -A --unstable --check build.ts",
|
||||
"plugs": "deno run -A --unstable --check build_plugs.ts",
|
||||
"watch-web": "deno run -A --unstable --check build.ts --watch",
|
||||
"watch-mobile": "deno run -A --unstable --check build_mobile.ts --watch",
|
||||
"watch-server": "deno run -A --unstable --check --watch silverbullet.ts",
|
||||
// The only reason to run a shell script is that deno task doesn't support globs yet (e.g. *.plug.yaml)
|
||||
"watch-plugs": "deno run -A --unstable --check build_plugs.ts -w",
|
||||
|
@ -13,11 +15,14 @@
|
|||
// Install lezer-generator with "npm install -g @lezer/generator"
|
||||
"generate": "deno run -A plugos/gen.ts && lezer-generator common/markdown_parser/query.grammar -o common/markdown_parser/parse-query.js",
|
||||
// Install npm dependencies for desktop app
|
||||
"desktop:install": "cd desktop && npm install",
|
||||
"desktop:deps": "cd desktop && npm install",
|
||||
// Run the desktop app for local development
|
||||
"desktop:run": "cd desktop && npm start",
|
||||
// Build the desktop app as a package for this platform
|
||||
"desktop:build": "deno task build && deno task bundle && cd desktop && npm run make"
|
||||
"desktop:build": "deno task build && deno task bundle && cd desktop && npm run make",
|
||||
// Mobile
|
||||
"mobile:deps": "cd mobile && npm install && npx cap sync",
|
||||
"mobile:build": "deno run -A --unstable --check build_mobile.ts && cd mobile && npx cap copy && npx cap open ios"
|
||||
},
|
||||
|
||||
"compilerOptions": {
|
||||
|
|
|
@ -17,6 +17,9 @@
|
|||
"$sb/": "./plug-api/",
|
||||
"handlebars": "https://esm.sh/handlebars",
|
||||
"@lezer/lr": "https://esm.sh/@lezer/lr@1.2.5?external=@lezer/common",
|
||||
"yaml": "https://deno.land/std/encoding/yaml.ts"
|
||||
"yaml": "https://deno.land/std/encoding/yaml.ts",
|
||||
|
||||
"@capacitor/core": "https://esm.sh/@capacitor/core@4.6.1",
|
||||
"@capacitor/filesystem": "https://esm.sh/@capacitor/filesystem@4.1.4?external=@capacitor/core"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
node_modules/
|
||||
*.map
|
||||
.DS_Store
|
||||
.sourcemaps
|
||||
dist/
|
|
@ -0,0 +1,12 @@
|
|||
## Created with Capacitor Create App
|
||||
|
||||
This app was created using [`@capacitor/create-app`](https://github.com/ionic-team/create-capacitor-app),
|
||||
and comes with a very minimal shell for building an app.
|
||||
|
||||
### Running this example
|
||||
|
||||
To run the provided example, you can use `npm start` command.
|
||||
|
||||
```bash
|
||||
npm start
|
||||
```
|
|
@ -0,0 +1,102 @@
|
|||
import { Editor } from "../web/editor.tsx";
|
||||
import { ensureAndLoadSettings, safeRun } from "../common/util.ts";
|
||||
import { Space } from "../common/spaces/space.ts";
|
||||
import { PlugSpacePrimitives } from "../server/hooks/plug_space_primitives.ts";
|
||||
import { PageNamespaceHook } from "../server/hooks/page_namespace.ts";
|
||||
import { SilverBulletHooks } from "../common/manifest.ts";
|
||||
import { System } from "../plugos/system.ts";
|
||||
import { BuiltinSettings } from "../web/types.ts";
|
||||
import { Directory } from "./deps.ts";
|
||||
import { CapacitorSpacePrimitives } from "./spaces/capacitor_space_primitives.ts";
|
||||
import { AssetBundlePlugSpacePrimitives } from "../common/spaces/asset_bundle_space_primitives.ts";
|
||||
|
||||
import assetBundle from "../dist/asset_bundle.json" assert { type: "json" };
|
||||
import { AssetBundle } from "../plugos/asset_bundle/bundle.ts";
|
||||
import {
|
||||
ensureTable as ensureStoreTable,
|
||||
storeSyscalls,
|
||||
} from "../plugos/syscalls/store.sqlite.ts";
|
||||
import { CapacitorDb } from "../plugos/sqlite/capacitor_sqlite.ts";
|
||||
import {
|
||||
ensureTable as ensurePageIndexTable,
|
||||
pageIndexSyscalls,
|
||||
} from "../server/syscalls/index.ts";
|
||||
import {
|
||||
ensureFTSTable,
|
||||
fullTextSearchSyscalls,
|
||||
} from "../plugos/syscalls/fulltext.sqlite.ts";
|
||||
import { FileMetaSpacePrimitives } from "../common/spaces/file_meta_space_primitives.ts";
|
||||
import { EventedSpacePrimitives } from "../common/spaces/evented_space_primitives.ts";
|
||||
import { EventHook } from "../plugos/hooks/event.ts";
|
||||
import { clientStoreSyscalls } from "./syscalls/clientStore.ts";
|
||||
import { sandboxFetchSyscalls } from "../plugos/syscalls/fetch.ts";
|
||||
|
||||
safeRun(async () => {
|
||||
// Instantiate a PlugOS system for the client
|
||||
const system = new System<SilverBulletHooks>();
|
||||
|
||||
// Attach the page namespace hook
|
||||
const namespaceHook = new PageNamespaceHook();
|
||||
system.addHook(namespaceHook);
|
||||
|
||||
// Event hook
|
||||
const eventHook = new EventHook();
|
||||
system.addHook(eventHook);
|
||||
|
||||
const db = new CapacitorDb("data.db");
|
||||
await db.init();
|
||||
|
||||
// for store
|
||||
await ensureStoreTable(db, "store");
|
||||
// for clientStore
|
||||
await ensureStoreTable(db, "localData");
|
||||
await ensurePageIndexTable(db);
|
||||
await ensureFTSTable(db, "fts");
|
||||
|
||||
const indexSyscalls = pageIndexSyscalls(db);
|
||||
|
||||
const spacePrimitives = new FileMetaSpacePrimitives(
|
||||
new AssetBundlePlugSpacePrimitives(
|
||||
new EventedSpacePrimitives(
|
||||
new PlugSpacePrimitives(
|
||||
new CapacitorSpacePrimitives(
|
||||
Directory.Documents,
|
||||
"",
|
||||
),
|
||||
namespaceHook,
|
||||
),
|
||||
eventHook,
|
||||
),
|
||||
new AssetBundle(assetBundle),
|
||||
),
|
||||
indexSyscalls,
|
||||
);
|
||||
|
||||
const serverSpace = new Space(spacePrimitives);
|
||||
serverSpace.watch();
|
||||
|
||||
const settings = await ensureAndLoadSettings(serverSpace) as BuiltinSettings;
|
||||
|
||||
// Register some mobile-specific syscall implementations
|
||||
system.registerSyscalls(
|
||||
[],
|
||||
storeSyscalls(db, "store"),
|
||||
indexSyscalls,
|
||||
clientStoreSyscalls(db),
|
||||
fullTextSearchSyscalls(db, "fts"),
|
||||
sandboxFetchSyscalls(),
|
||||
);
|
||||
|
||||
console.log("Booting...");
|
||||
|
||||
const editor = new Editor(
|
||||
serverSpace,
|
||||
system,
|
||||
eventHook,
|
||||
document.getElementById("sb-root")!,
|
||||
"",
|
||||
settings,
|
||||
);
|
||||
|
||||
await editor.init();
|
||||
});
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"appId": "md.silverbullet",
|
||||
"appName": "SilverBullet",
|
||||
"bundledWebRuntime": false,
|
||||
"webDir": "dist",
|
||||
"backgroundColor": "#000",
|
||||
"ios": {
|
||||
"contentInset": "always"
|
||||
},
|
||||
"plugins": {
|
||||
"SplashScreen": {
|
||||
"launchShowDuration": 0
|
||||
},
|
||||
"CapacitorSQLite": {
|
||||
"iosDatabaseLocation": "Library"
|
||||
},
|
||||
"CapacitorHttp": {
|
||||
"enabled": true
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
export { Capacitor } from "@capacitor/core";
|
||||
export { Directory, Encoding, Filesystem } from "@capacitor/filesystem";
|
||||
export type { WriteFileResult } from "@capacitor/filesystem";
|
|
@ -0,0 +1,47 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport"
|
||||
content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" />
|
||||
<base href="/" />
|
||||
|
||||
<title>Silver Bullet</title>
|
||||
<script>
|
||||
Deno = {
|
||||
args: [],
|
||||
build: {
|
||||
arch: "x86_64",
|
||||
},
|
||||
env: {
|
||||
get(key) {
|
||||
// return undefined;
|
||||
},
|
||||
},
|
||||
errors: {
|
||||
AlreadyExists: class extends Error { },
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style>
|
||||
html,
|
||||
body {
|
||||
margin: 0;
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
<link rel="stylesheet" href="/main.css" />
|
||||
<script type="module" src="/client.js"></script>
|
||||
<link rel="manifest" href="/manifest.json" -->
|
||||
<link rel="icon" type="image/x-icon" href="/favicon.png" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="sb-root"></div>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -0,0 +1,13 @@
|
|||
App/build
|
||||
App/Pods
|
||||
App/Podfile.lock
|
||||
App/App/public
|
||||
DerivedData
|
||||
xcuserdata
|
||||
|
||||
# Cordova plugins for Capacitor
|
||||
capacitor-cordova-ios-plugins
|
||||
|
||||
# Generated Config files
|
||||
App/App/capacitor.config.json
|
||||
App/App/config.xml
|
|
@ -0,0 +1,422 @@
|
|||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 48;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
2493DD8E3237F110A3166EDB /* Pods_SilverBullet.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0B2AB7E92525621074064EB5 /* Pods_SilverBullet.framework */; };
|
||||
2FAD9763203C412B000D30F8 /* config.xml in Resources */ = {isa = PBXBuildFile; fileRef = 2FAD9762203C412B000D30F8 /* config.xml */; };
|
||||
50379B232058CBB4000EE86E /* capacitor.config.json in Resources */ = {isa = PBXBuildFile; fileRef = 50379B222058CBB4000EE86E /* capacitor.config.json */; };
|
||||
504EC3081FED79650016851F /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 504EC3071FED79650016851F /* AppDelegate.swift */; };
|
||||
504EC30D1FED79650016851F /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 504EC30B1FED79650016851F /* Main.storyboard */; };
|
||||
504EC30F1FED79650016851F /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 504EC30E1FED79650016851F /* Assets.xcassets */; };
|
||||
504EC3121FED79650016851F /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 504EC3101FED79650016851F /* LaunchScreen.storyboard */; };
|
||||
50B271D11FEDC1A000F3C39B /* public in Resources */ = {isa = PBXBuildFile; fileRef = 50B271D01FEDC1A000F3C39B /* public */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
0B2AB7E92525621074064EB5 /* Pods_SilverBullet.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_SilverBullet.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
2E06859990AF304187A3CBA8 /* Pods-SilverBullet.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SilverBullet.debug.xcconfig"; path = "Pods/Target Support Files/Pods-SilverBullet/Pods-SilverBullet.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
2E4EFA801479B66C1B2AD68F /* Pods-SilverBullet.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SilverBullet.release.xcconfig"; path = "Pods/Target Support Files/Pods-SilverBullet/Pods-SilverBullet.release.xcconfig"; sourceTree = "<group>"; };
|
||||
2FAD9762203C412B000D30F8 /* config.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = config.xml; sourceTree = "<group>"; };
|
||||
50379B222058CBB4000EE86E /* capacitor.config.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = capacitor.config.json; sourceTree = "<group>"; };
|
||||
504EC3041FED79650016851F /* SilverBullet.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SilverBullet.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
504EC3071FED79650016851F /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||
504EC30C1FED79650016851F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
|
||||
504EC30E1FED79650016851F /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||
504EC3111FED79650016851F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||
504EC3131FED79650016851F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
50B271D01FEDC1A000F3C39B /* public */ = {isa = PBXFileReference; lastKnownFileType = folder; path = public; sourceTree = "<group>"; };
|
||||
AF51FD2D460BCFE21FA515B2 /* Pods-App.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App.release.xcconfig"; path = "Pods/Target Support Files/Pods-App/Pods-App.release.xcconfig"; sourceTree = "<group>"; };
|
||||
FC68EB0AF532CFC21C3344DD /* Pods-App.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App.debug.xcconfig"; path = "Pods/Target Support Files/Pods-App/Pods-App.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
504EC3011FED79650016851F /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
2493DD8E3237F110A3166EDB /* Pods_SilverBullet.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
27E2DDA53C4D2A4D1A88CE4A /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0B2AB7E92525621074064EB5 /* Pods_SilverBullet.framework */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
504EC2FB1FED79650016851F = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
504EC3061FED79650016851F /* App */,
|
||||
504EC3051FED79650016851F /* Products */,
|
||||
7F8756D8B27F46E3366F6CEA /* Pods */,
|
||||
27E2DDA53C4D2A4D1A88CE4A /* Frameworks */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
504EC3051FED79650016851F /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
504EC3041FED79650016851F /* SilverBullet.app */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
504EC3061FED79650016851F /* App */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
50379B222058CBB4000EE86E /* capacitor.config.json */,
|
||||
504EC3071FED79650016851F /* AppDelegate.swift */,
|
||||
504EC30B1FED79650016851F /* Main.storyboard */,
|
||||
504EC30E1FED79650016851F /* Assets.xcassets */,
|
||||
504EC3101FED79650016851F /* LaunchScreen.storyboard */,
|
||||
504EC3131FED79650016851F /* Info.plist */,
|
||||
2FAD9762203C412B000D30F8 /* config.xml */,
|
||||
50B271D01FEDC1A000F3C39B /* public */,
|
||||
);
|
||||
path = App;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
7F8756D8B27F46E3366F6CEA /* Pods */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FC68EB0AF532CFC21C3344DD /* Pods-App.debug.xcconfig */,
|
||||
AF51FD2D460BCFE21FA515B2 /* Pods-App.release.xcconfig */,
|
||||
2E06859990AF304187A3CBA8 /* Pods-SilverBullet.debug.xcconfig */,
|
||||
2E4EFA801479B66C1B2AD68F /* Pods-SilverBullet.release.xcconfig */,
|
||||
);
|
||||
name = Pods;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
504EC3031FED79650016851F /* SilverBullet */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 504EC3161FED79650016851F /* Build configuration list for PBXNativeTarget "SilverBullet" */;
|
||||
buildPhases = (
|
||||
6634F4EFEBD30273BCE97C65 /* [CP] Check Pods Manifest.lock */,
|
||||
504EC3001FED79650016851F /* Sources */,
|
||||
504EC3011FED79650016851F /* Frameworks */,
|
||||
504EC3021FED79650016851F /* Resources */,
|
||||
9592DBEFFC6D2A0C8D5DEB22 /* [CP] Embed Pods Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = SilverBullet;
|
||||
productName = App;
|
||||
productReference = 504EC3041FED79650016851F /* SilverBullet.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
504EC2FC1FED79650016851F /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastSwiftUpdateCheck = 0920;
|
||||
LastUpgradeCheck = 0920;
|
||||
TargetAttributes = {
|
||||
504EC3031FED79650016851F = {
|
||||
CreatedOnToolsVersion = 9.2;
|
||||
LastSwiftMigration = 1100;
|
||||
ProvisioningStyle = Automatic;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = 504EC2FF1FED79650016851F /* Build configuration list for PBXProject "App" */;
|
||||
compatibilityVersion = "Xcode 8.0";
|
||||
developmentRegion = en;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
Base,
|
||||
);
|
||||
mainGroup = 504EC2FB1FED79650016851F;
|
||||
productRefGroup = 504EC3051FED79650016851F /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
504EC3031FED79650016851F /* SilverBullet */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
504EC3021FED79650016851F /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
504EC3121FED79650016851F /* LaunchScreen.storyboard in Resources */,
|
||||
50B271D11FEDC1A000F3C39B /* public in Resources */,
|
||||
504EC30F1FED79650016851F /* Assets.xcassets in Resources */,
|
||||
50379B232058CBB4000EE86E /* capacitor.config.json in Resources */,
|
||||
504EC30D1FED79650016851F /* Main.storyboard in Resources */,
|
||||
2FAD9763203C412B000D30F8 /* config.xml in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXShellScriptBuildPhase section */
|
||||
6634F4EFEBD30273BCE97C65 /* [CP] Check Pods Manifest.lock */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
|
||||
"${PODS_ROOT}/Manifest.lock",
|
||||
);
|
||||
name = "[CP] Check Pods Manifest.lock";
|
||||
outputPaths = (
|
||||
"$(DERIVED_FILE_DIR)/Pods-SilverBullet-checkManifestLockResult.txt",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
9592DBEFFC6D2A0C8D5DEB22 /* [CP] Embed Pods Frameworks */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = "[CP] Embed Pods Frameworks";
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-SilverBullet/Pods-SilverBullet-frameworks.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
/* End PBXShellScriptBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
504EC3001FED79650016851F /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
504EC3081FED79650016851F /* AppDelegate.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXVariantGroup section */
|
||||
504EC30B1FED79650016851F /* Main.storyboard */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
504EC30C1FED79650016851F /* Base */,
|
||||
);
|
||||
name = Main.storyboard;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
504EC3101FED79650016851F /* LaunchScreen.storyboard */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
504EC3111FED79650016851F /* Base */,
|
||||
);
|
||||
name = LaunchScreen.storyboard;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXVariantGroup section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
504EC3141FED79650016851F /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
504EC3151FED79650016851F /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
504EC3171FED79650016851F /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 2E06859990AF304187A3CBA8 /* Pods-SilverBullet.debug.xcconfig */;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEVELOPMENT_TEAM = Z92J6WM6X8;
|
||||
INFOPLIST_FILE = App/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = SilverBullet;
|
||||
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.productivity";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
MARKETING_VERSION = 1.0;
|
||||
OTHER_SWIFT_FLAGS = "$(inherited) \"-D\" \"COCOAPODS\" \"-DDEBUG\"";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = md.silverbullet;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
504EC3181FED79650016851F /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 2E4EFA801479B66C1B2AD68F /* Pods-SilverBullet.release.xcconfig */;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEVELOPMENT_TEAM = Z92J6WM6X8;
|
||||
INFOPLIST_FILE = App/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = SilverBullet;
|
||||
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.productivity";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
MARKETING_VERSION = 1.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = md.silverbullet;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
504EC2FF1FED79650016851F /* Build configuration list for PBXProject "App" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
504EC3141FED79650016851F /* Debug */,
|
||||
504EC3151FED79650016851F /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
504EC3161FED79650016851F /* Build configuration list for PBXNativeTarget "SilverBullet" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
504EC3171FED79650016851F /* Debug */,
|
||||
504EC3181FED79650016851F /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 504EC2FC1FED79650016851F /* Project object */;
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:App.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "group:App.xcodeproj">
|
||||
</FileRef>
|
||||
<FileRef
|
||||
location = "group:Pods/Pods.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDEDidComputeMac32BitWarning</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,49 @@
|
|||
import UIKit
|
||||
import Capacitor
|
||||
|
||||
@UIApplicationMain
|
||||
class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
|
||||
var window: UIWindow?
|
||||
|
||||
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
|
||||
// Override point for customization after application launch.
|
||||
return true
|
||||
}
|
||||
|
||||
func applicationWillResignActive(_ application: UIApplication) {
|
||||
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
|
||||
// Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
|
||||
}
|
||||
|
||||
func applicationDidEnterBackground(_ application: UIApplication) {
|
||||
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
|
||||
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
|
||||
}
|
||||
|
||||
func applicationWillEnterForeground(_ application: UIApplication) {
|
||||
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
|
||||
}
|
||||
|
||||
func applicationDidBecomeActive(_ application: UIApplication) {
|
||||
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
|
||||
}
|
||||
|
||||
func applicationWillTerminate(_ application: UIApplication) {
|
||||
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
|
||||
}
|
||||
|
||||
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
|
||||
// Called when the app was launched with a url. Feel free to add additional processing here,
|
||||
// but if you want the App API to support tracking app url opens, make sure to keep this call
|
||||
return ApplicationDelegateProxy.shared.application(app, open: url, options: options)
|
||||
}
|
||||
|
||||
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
|
||||
// Called when the app was launched with an activity, including Universal Links.
|
||||
// Feel free to add additional processing here, but if you want the App API to support
|
||||
// tracking app url opens, make sure to keep this call
|
||||
return ApplicationDelegateProxy.shared.application(application, continue: userActivity, restorationHandler: restorationHandler)
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "icon.png",
|
||||
"idiom" : "universal",
|
||||
"platform" : "ios",
|
||||
"size" : "1024x1024"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 650 KiB |
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "splash-2732x2732-2.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "splash-2732x2732-1.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "splash-2732x2732.png",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 40 KiB |
Binary file not shown.
After Width: | Height: | Size: 40 KiB |
Binary file not shown.
After Width: | Height: | Size: 40 KiB |
|
@ -0,0 +1,32 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="17132" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
|
||||
<device id="retina4_7" orientation="portrait" appearance="light"/>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17105"/>
|
||||
<capability name="System colors in document resources" minToolsVersion="11.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--View Controller-->
|
||||
<scene sceneID="EHf-IW-A2E">
|
||||
<objects>
|
||||
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
|
||||
<imageView key="view" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="Splash" id="snD-IY-ifK">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
|
||||
</imageView>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="53" y="375"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
<resources>
|
||||
<image name="Splash" width="1366" height="1366"/>
|
||||
<systemColor name="systemBackgroundColor">
|
||||
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</systemColor>
|
||||
</resources>
|
||||
</document>
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14111" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
|
||||
<device id="retina4_7" orientation="portrait">
|
||||
<adaptation id="fullscreen"/>
|
||||
</device>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14088"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--Bridge View Controller-->
|
||||
<scene sceneID="tne-QT-ifu">
|
||||
<objects>
|
||||
<viewController id="BYZ-38-t0r" customClass="CAPBridgeViewController" customModule="Capacitor" sceneMemberID="viewController"/>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
</scene>
|
||||
</scenes>
|
||||
</document>
|
|
@ -0,0 +1,72 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>SilverBullet</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>$(MARKETING_VERSION)</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>LSSupportsOpeningDocumentsInPlace</key>
|
||||
<true/>
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
<true/>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
<true/>
|
||||
<key>NSExceptionDomains</key>
|
||||
<dict>
|
||||
<key>localhost</key>
|
||||
<dict>
|
||||
<key>NSExceptionAllowsInsecureHTTPLoads</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>UIFileSharingEnabled</key>
|
||||
<true/>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>LaunchScreen</string>
|
||||
<key>UIMainStoryboardFile</key>
|
||||
<string>Main</string>
|
||||
<key>UIRequiredDeviceCapabilities</key>
|
||||
<array>
|
||||
<string>armv7</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||
</array>
|
||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||
<true/>
|
||||
<key>WKAppBoundDomains</key>
|
||||
<array>
|
||||
<string>192.168.0.3</string>
|
||||
<string>127.0.0.1</string>
|
||||
<string>localhost</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,28 @@
|
|||
require_relative '../../node_modules/@capacitor/ios/scripts/pods_helpers'
|
||||
|
||||
platform :ios, '13.0'
|
||||
use_frameworks!
|
||||
|
||||
# workaround to avoid Xcode caching of Pods that requires
|
||||
# Product -> Clean Build Folder after new Cordova plugins installed
|
||||
# Requires CocoaPods 1.6 or newer
|
||||
install! 'cocoapods', :disable_input_output_paths => true
|
||||
|
||||
def capacitor_pods
|
||||
pod 'Capacitor', :path => '../../node_modules/@capacitor/ios'
|
||||
pod 'CapacitorCordova', :path => '../../node_modules/@capacitor/ios'
|
||||
pod 'CapacitorCommunitySqlite', :path => '../../node_modules/@capacitor-community/sqlite'
|
||||
pod 'CapacitorApp', :path => '../../node_modules/@capacitor/app'
|
||||
pod 'CapacitorFilesystem', :path => '../../node_modules/@capacitor/filesystem'
|
||||
pod 'CapacitorKeyboard', :path => '../../node_modules/@capacitor/keyboard'
|
||||
pod 'CapacitorSplashScreen', :path => '../../node_modules/@capacitor/splash-screen'
|
||||
end
|
||||
|
||||
target 'SilverBullet' do
|
||||
capacitor_pods
|
||||
# Add your Pods here
|
||||
end
|
||||
|
||||
post_install do |installer|
|
||||
assertDeploymentTarget(installer)
|
||||
end
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,32 @@
|
|||
{
|
||||
"name": "capacitor-app",
|
||||
"version": "1.0.0",
|
||||
"description": "An Amazing Capacitor App",
|
||||
"main": "index.js",
|
||||
"keywords": [
|
||||
"capacitor",
|
||||
"mobile"
|
||||
],
|
||||
"scripts": {
|
||||
"start": "vite",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@capacitor-community/sqlite": "^4.6.0",
|
||||
"@capacitor/android": "^4.6.1",
|
||||
"@capacitor/app": "^4.1.1",
|
||||
"@capacitor/core": "latest",
|
||||
"@capacitor/filesystem": "^4.1.4",
|
||||
"@capacitor/ios": "^4.6.1",
|
||||
"@capacitor/keyboard": "^4.1.0",
|
||||
"@capacitor/splash-screen": "latest",
|
||||
"cordova-res": "^0.15.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@capacitor/cli": "latest",
|
||||
"vite": "^2.9.13"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC"
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 748 KiB |
|
@ -0,0 +1,158 @@
|
|||
import {
|
||||
FileData,
|
||||
FileEncoding,
|
||||
SpacePrimitives,
|
||||
} from "../../common/spaces/space_primitives.ts";
|
||||
import type { FileMeta } from "../../common/types.ts";
|
||||
import {
|
||||
base64Decode,
|
||||
base64Encode,
|
||||
} from "../../plugos/asset_bundle/base64.ts";
|
||||
import type { Plug } from "../../plugos/plug.ts";
|
||||
import { Directory, Encoding, Filesystem } from "../deps.ts";
|
||||
import { mime } from "../../plugos/deps.ts";
|
||||
|
||||
export class CapacitorSpacePrimitives implements SpacePrimitives {
|
||||
constructor(readonly source: Directory, readonly root: string) {
|
||||
}
|
||||
|
||||
async fetchFileList(): Promise<FileMeta[]> {
|
||||
const allFiles: FileMeta[] = [];
|
||||
const directory = this.source;
|
||||
const root = this.root;
|
||||
|
||||
async function readAllFiles(dir: string) {
|
||||
const files = await Filesystem.readdir({
|
||||
path: `${root}/${dir}`,
|
||||
directory,
|
||||
});
|
||||
for (const file of files.files) {
|
||||
if (file.type === "file") {
|
||||
allFiles.push({
|
||||
name: `${dir}/${file.name}`.substring(1),
|
||||
lastModified: file.mtime,
|
||||
perm: "rw",
|
||||
contentType: mime.getType(file.name) || "application/octet-stream",
|
||||
size: file.size,
|
||||
});
|
||||
} else { // Directory
|
||||
await readAllFiles(`${dir}/${file.name}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
await readAllFiles("");
|
||||
console.log("allFiles", allFiles);
|
||||
return allFiles;
|
||||
}
|
||||
async readFile(
|
||||
name: string,
|
||||
encoding: FileEncoding,
|
||||
): Promise<{ data: FileData; meta: FileMeta }> {
|
||||
let data: FileData | undefined;
|
||||
try {
|
||||
switch (encoding) {
|
||||
case "string":
|
||||
data = (await Filesystem.readFile({
|
||||
path: this.root + name,
|
||||
directory: this.source,
|
||||
encoding: Encoding.UTF8,
|
||||
})).data;
|
||||
break;
|
||||
case "arraybuffer": {
|
||||
const b64Data = (await Filesystem.readFile({
|
||||
path: this.root + name,
|
||||
directory: this.source,
|
||||
})).data;
|
||||
data = base64Decode(b64Data);
|
||||
break;
|
||||
}
|
||||
case "dataurl": {
|
||||
const b64Data = (await Filesystem.readFile({
|
||||
path: this.root + name,
|
||||
directory: this.source,
|
||||
})).data;
|
||||
data = `data:${
|
||||
mime.getType(name) || "application/octet-stream"
|
||||
};base64,${b64Data}`;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return {
|
||||
data,
|
||||
meta: await this.getFileMeta(name),
|
||||
};
|
||||
} catch (e: any) {
|
||||
throw new Error(`Page not found`);
|
||||
}
|
||||
}
|
||||
async getFileMeta(name: string): Promise<FileMeta> {
|
||||
try {
|
||||
const statResult = await Filesystem.stat({
|
||||
path: this.root + name,
|
||||
directory: this.source,
|
||||
});
|
||||
return {
|
||||
name,
|
||||
contentType: mime.getType(name) || "application/octet-stream",
|
||||
lastModified: statResult.mtime,
|
||||
perm: "rw",
|
||||
size: statResult.size,
|
||||
};
|
||||
} catch (e: any) {
|
||||
console.error("Error getting file meta", e.message);
|
||||
throw new Error(`Page not found`);
|
||||
}
|
||||
}
|
||||
async writeFile(
|
||||
name: string,
|
||||
encoding: FileEncoding,
|
||||
data: FileData,
|
||||
): Promise<FileMeta> {
|
||||
switch (encoding) {
|
||||
case "string":
|
||||
await Filesystem.writeFile({
|
||||
path: this.root + name,
|
||||
directory: this.source,
|
||||
encoding: Encoding.UTF8,
|
||||
data: data as string,
|
||||
recursive: true,
|
||||
});
|
||||
break;
|
||||
case "arraybuffer":
|
||||
await Filesystem.writeFile({
|
||||
path: this.root + name,
|
||||
directory: this.source,
|
||||
data: base64Encode(new Uint8Array(data as ArrayBuffer)),
|
||||
recursive: true,
|
||||
});
|
||||
break;
|
||||
case "dataurl":
|
||||
await Filesystem.writeFile({
|
||||
path: this.root + name,
|
||||
directory: this.source,
|
||||
data: (data as string).split(";base64,")[1],
|
||||
recursive: true,
|
||||
});
|
||||
break;
|
||||
}
|
||||
return this.getFileMeta(name);
|
||||
}
|
||||
|
||||
async deleteFile(name: string): Promise<void> {
|
||||
await Filesystem.deleteFile({
|
||||
path: this.root + name,
|
||||
directory: this.source,
|
||||
});
|
||||
}
|
||||
proxySyscall(plug: Plug<any>, name: string, args: any[]): Promise<any> {
|
||||
return plug.syscall(name, args);
|
||||
}
|
||||
invokeFunction(
|
||||
plug: Plug<any>,
|
||||
_env: string,
|
||||
name: string,
|
||||
args: any[],
|
||||
): Promise<any> {
|
||||
return plug.invoke(name, args);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
import { proxySyscalls } from "../../plugos/syscalls/transport.ts";
|
||||
import { SysCallMapping } from "../../plugos/system.ts";
|
||||
import { storeSyscalls } from "../../plugos/syscalls/store.sqlite.ts";
|
||||
import { ISQLite } from "../../plugos/sqlite/sqlite_interface.ts";
|
||||
|
||||
export function clientStoreSyscalls(db: ISQLite): SysCallMapping {
|
||||
const storeCalls = storeSyscalls(db, "localData");
|
||||
return proxySyscalls(
|
||||
["clientStore.get", "clientStore.set", "clientStore.delete"],
|
||||
(ctx, name, ...args) => {
|
||||
return storeCalls[name.replace("clientStore.", "store.")](ctx, ...args);
|
||||
},
|
||||
);
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
import { base64Decode } from "../../plugos/asset_bundle/base64.ts";
|
||||
|
||||
export type SandboxFetchRequest = {
|
||||
method?: string;
|
||||
headers?: Record<string, string>;
|
||||
};
|
||||
|
||||
export type SandboxFetchResponse = {
|
||||
ok: boolean;
|
||||
status: number;
|
||||
headers: Record<string, string>;
|
||||
// We base64 encode the body because the body can be binary data that we have to push through the worker boundary
|
||||
base64Body: string;
|
||||
};
|
||||
|
||||
export function sandboxFetch(
|
||||
url: string,
|
||||
options?: SandboxFetchRequest,
|
||||
): Promise<SandboxFetchResponse> {
|
||||
// @ts-ignore: monkey patching fetch
|
||||
return syscall("sandboxFetch.fetch", url, options);
|
||||
}
|
||||
|
||||
export function monkeyPatchFetch() {
|
||||
// @ts-ignore: monkey patching fetch
|
||||
globalThis.fetch = async function (
|
||||
url: string,
|
||||
init?: RequestInit,
|
||||
): Promise<Response> {
|
||||
const r = await sandboxFetch(
|
||||
url,
|
||||
init && {
|
||||
method: init.method,
|
||||
headers: init.headers as Record<string, string>,
|
||||
},
|
||||
);
|
||||
return new Response(base64Decode(r.base64Body), {
|
||||
status: r.status,
|
||||
headers: r.headers,
|
||||
});
|
||||
};
|
||||
}
|
|
@ -5,3 +5,5 @@ export { expandGlobSync } from "https://deno.land/std@0.165.0/fs/mod.ts";
|
|||
export { mime } from "https://deno.land/x/mimetypes@v1.0.0/mod.ts";
|
||||
export { default as cacheDir } from "https://deno.land/x/cache_dir@0.2.0/mod.ts";
|
||||
export * as flags from "https://deno.land/std@0.165.0/flags/mod.ts";
|
||||
|
||||
export { CapacitorSQLite } from "https://esm.sh/@capacitor-community/sqlite@4.6.0?external=@capacitor/core";
|
||||
|
|
|
@ -48,8 +48,8 @@ export function createSandbox(plug: Plug<any>) {
|
|||
type: "module",
|
||||
deno: {
|
||||
permissions: {
|
||||
// Allow network access and servers (main use case: fetch)
|
||||
net: true,
|
||||
// Disallow network access
|
||||
net: false,
|
||||
// This is required for console logging to work, apparently?
|
||||
env: true,
|
||||
// No talking to native code
|
||||
|
|
|
@ -159,3 +159,7 @@ self.addEventListener("message", (event: { data: WorkerMessage }) => {
|
|||
}
|
||||
});
|
||||
});
|
||||
|
||||
import { monkeyPatchFetch } from "../../plug-api/plugos-syscall/fetch.ts";
|
||||
|
||||
monkeyPatchFetch();
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
{
|
||||
"worker.js": "data:application/javascript;base64,KCgpID0+IHsgdmFyIG1vZD0oKCk9PntmdW5jdGlvbiBjKHMpe3MoKS5jYXRjaChlPT57Y29uc29sZS5lcnJvcigiQ2F1Z2h0IGVycm9yIixlLm1lc3NhZ2UpfSl9dmFyIGE9Y2xhc3N7Y29uc3RydWN0b3IoZSxuPSEwKXt0aGlzLnByaW50PW4sdGhpcy5jYWxsYmFjaz1lfWxvZyguLi5lKXt0aGlzLnB1c2goImxvZyIsZSl9d2FybiguLi5lKXt0aGlzLnB1c2goIndhcm4iLGUpfWVycm9yKC4uLmUpe3RoaXMucHVzaCgiZXJyb3IiLGUpfWluZm8oLi4uZSl7dGhpcy5wdXNoKCJpbmZvIixlKX1wdXNoKGUsbil7dGhpcy5jYWxsYmFjayhlLHRoaXMubG9nTWVzc2FnZShuKSksdGhpcy5wcmludCYmY29uc29sZVtlXSguLi5uKX1sb2dNZXNzYWdlKGUpe2xldCBuPVtdO2ZvcihsZXQgciBvZiBlKXN3aXRjaCh0eXBlb2Ygcil7Y2FzZSJzdHJpbmciOmNhc2UibnVtYmVyIjpuLnB1c2goIiIrcik7YnJlYWs7Y2FzZSJ1bmRlZmluZWQiOm4ucHVzaCgidW5kZWZpbmVkIik7YnJlYWs7ZGVmYXVsdDp0cnl7bGV0IG89SlNPTi5zdHJpbmdpZnkocixudWxsLDIpO28ubGVuZ3RoPjUwMCYmKG89by5zdWJzdHJpbmcoMCw1MDApKyIuLi4iKSxuLnB1c2gobyl9Y2F0Y2h7bi5wdXNoKCJbY2lyY3VsYXIgb2JqZWN0XSIpfX1yZXR1cm4gbi5qb2luKCIgIil9fTt0eXBlb2YgRGVubz4idSImJihzZWxmLkRlbm89e2FyZ3M6W10sYnVpbGQ6e2FyY2g6Ing4Nl82NCJ9LGVudjp7Z2V0KCl7fX19KTt2YXIgZD1uZXcgTWFwLGk9bmV3IE1hcDtmdW5jdGlvbiB0KHMpe3R5cGVvZiB3aW5kb3c8InUiJiZ3aW5kb3cucGFyZW50IT09d2luZG93P3dpbmRvdy5wYXJlbnQucG9zdE1lc3NhZ2UocywiKiIpOnNlbGYucG9zdE1lc3NhZ2Uocyl9dmFyIGw9MDtzZWxmLnN5c2NhbGw9YXN5bmMocywuLi5lKT0+YXdhaXQgbmV3IFByb21pc2UoKG4scik9PntsKyssaS5zZXQobCx7cmVzb2x2ZTpuLHJlamVjdDpyfSksdCh7dHlwZToic3lzY2FsbCIsaWQ6bCxuYW1lOnMsYXJnczplfSl9KTt2YXIgdT1uZXcgTWFwO3NlbGYucmVxdWlyZT1zPT57bGV0IGU9dS5nZXQocyk7aWYoIWUpdGhyb3cgbmV3IEVycm9yKGBEeW5hbWljYWxseSBpbXBvcnRpbmcgbm9uLXByZWxvYWRlZCBsaWJyYXJ5ICR7c31gKTtyZXR1cm4gZX07c2VsZi5jb25zb2xlPW5ldyBhKChzLGUpPT57dCh7dHlwZToibG9nIixsZXZlbDpzLG1lc3NhZ2U6ZX0pfSwhMSk7ZnVuY3Rpb24gZyhzKXtyZXR1cm5gcmV0dXJuICgke3N9KVsiZGVmYXVsdCJdYH1zZWxmLmFkZEV2ZW50TGlzdGVuZXIoIm1lc3NhZ2UiLHM9PntjKGFzeW5jKCk9PntsZXQgZT1zLmRhdGE7c3dpdGNoKGUudHlwZSl7Y2FzZSJsb2FkIjp7bGV0IG49bmV3IEZ1bmN0aW9uKGcoZS5jb2RlKSk7ZC5zZXQoZS5uYW1lLG4oKSksdCh7dHlwZToiaW5pdGVkIixuYW1lOmUubmFtZX0pfWJyZWFrO2Nhc2UibG9hZC1kZXBlbmRlbmN5Ijp7bGV0IHI9bmV3IEZ1bmN0aW9uKGByZXR1cm4gJHtlLmNvZGV9YCkoKTt1LnNldChlLm5hbWUsciksdCh7dHlwZToiZGVwZW5kZW5jeS1pbml0ZWQiLG5hbWU6ZS5uYW1lfSl9YnJlYWs7Y2FzZSJpbnZva2UiOntsZXQgbj1kLmdldChlLm5hbWUpO2lmKCFuKXRocm93IG5ldyBFcnJvcihgRnVuY3Rpb24gbm90IGxvYWRlZDogJHtlLm5hbWV9YCk7dHJ5e2xldCByPWF3YWl0IFByb21pc2UucmVzb2x2ZShuKC4uLmUuYXJnc3x8W10pKTt0KHt0eXBlOiJyZXN1bHQiLGlkOmUuaWQscmVzdWx0OnJ9KX1jYXRjaChyKXt0KHt0eXBlOiJyZXN1bHQiLGlkOmUuaWQsZXJyb3I6ci5tZXNzYWdlLHN0YWNrOnIuc3RhY2t9KX19YnJlYWs7Y2FzZSJzeXNjYWxsLXJlc3BvbnNlIjp7bGV0IG49ZS5pZCxyPWkuZ2V0KG4pO2lmKCFyKXRocm93IGNvbnNvbGUubG9nKCJDdXJyZW50IG91dHN0YW5kaW5nIHJlcXVlc3RzIixpLCJsb29raW5nIHVwIixuKSxFcnJvcigiSW52YWxpZCByZXF1ZXN0IGlkIik7aS5kZWxldGUobiksZS5lcnJvcj9yLnJlamVjdChuZXcgRXJyb3IoZS5lcnJvcikpOnIucmVzb2x2ZShlLnJlc3VsdCl9YnJlYWt9fSl9KTt9KSgpOwogcmV0dXJuIG1vZDt9KSgp"
|
||||
"worker.js": "data:application/javascript;base64,KCgpID0+IHsgdmFyIG1vZD0oKCk9PntmdW5jdGlvbiBsKHQpe3QoKS5jYXRjaChlPT57Y29uc29sZS5lcnJvcigiQ2F1Z2h0IGVycm9yIixlLm1lc3NhZ2UpfSl9dmFyIGE9Y2xhc3N7Y29uc3RydWN0b3IoZSxuPSEwKXt0aGlzLnByaW50PW4sdGhpcy5jYWxsYmFjaz1lfWxvZyguLi5lKXt0aGlzLnB1c2goImxvZyIsZSl9d2FybiguLi5lKXt0aGlzLnB1c2goIndhcm4iLGUpfWVycm9yKC4uLmUpe3RoaXMucHVzaCgiZXJyb3IiLGUpfWluZm8oLi4uZSl7dGhpcy5wdXNoKCJpbmZvIixlKX1wdXNoKGUsbil7dGhpcy5jYWxsYmFjayhlLHRoaXMubG9nTWVzc2FnZShuKSksdGhpcy5wcmludCYmY29uc29sZVtlXSguLi5uKX1sb2dNZXNzYWdlKGUpe2xldCBuPVtdO2ZvcihsZXQgciBvZiBlKXN3aXRjaCh0eXBlb2Ygcil7Y2FzZSJzdHJpbmciOmNhc2UibnVtYmVyIjpuLnB1c2goIiIrcik7YnJlYWs7Y2FzZSJ1bmRlZmluZWQiOm4ucHVzaCgidW5kZWZpbmVkIik7YnJlYWs7ZGVmYXVsdDp0cnl7bGV0IHM9SlNPTi5zdHJpbmdpZnkocixudWxsLDIpO3MubGVuZ3RoPjUwMCYmKHM9cy5zdWJzdHJpbmcoMCw1MDApKyIuLi4iKSxuLnB1c2gocyl9Y2F0Y2h7bi5wdXNoKCJbY2lyY3VsYXIgb2JqZWN0XSIpfX1yZXR1cm4gbi5qb2luKCIgIil9fTtmdW5jdGlvbiBkKHQpe2xldCBlPWF0b2IodCksbj1lLmxlbmd0aCxyPW5ldyBVaW50OEFycmF5KG4pO2ZvcihsZXQgcz0wO3M8bjtzKyspcltzXT1lLmNoYXJDb2RlQXQocyk7cmV0dXJuIHJ9ZnVuY3Rpb24geSh0LGUpe3JldHVybiBzeXNjYWxsKCJzYW5kYm94RmV0Y2guZmV0Y2giLHQsZSl9ZnVuY3Rpb24gdSgpe2dsb2JhbFRoaXMuZmV0Y2g9YXN5bmMgZnVuY3Rpb24odCxlKXtsZXQgbj1hd2FpdCB5KHQsZSYme21ldGhvZDplLm1ldGhvZCxoZWFkZXJzOmUuaGVhZGVyc30pO3JldHVybiBuZXcgUmVzcG9uc2UoZChuLmJhc2U2NEJvZHkpLHtzdGF0dXM6bi5zdGF0dXMsaGVhZGVyczpuLmhlYWRlcnN9KX19dHlwZW9mIERlbm8+InUiJiYoc2VsZi5EZW5vPXthcmdzOltdLGJ1aWxkOnthcmNoOiJ4ODZfNjQifSxlbnY6e2dldCgpe319fSk7dmFyIGc9bmV3IE1hcCxpPW5ldyBNYXA7ZnVuY3Rpb24gbyh0KXt0eXBlb2Ygd2luZG93PCJ1IiYmd2luZG93LnBhcmVudCE9PXdpbmRvdz93aW5kb3cucGFyZW50LnBvc3RNZXNzYWdlKHQsIioiKTpzZWxmLnBvc3RNZXNzYWdlKHQpfXZhciBjPTA7c2VsZi5zeXNjYWxsPWFzeW5jKHQsLi4uZSk9PmF3YWl0IG5ldyBQcm9taXNlKChuLHIpPT57YysrLGkuc2V0KGMse3Jlc29sdmU6bixyZWplY3Q6cn0pLG8oe3R5cGU6InN5c2NhbGwiLGlkOmMsbmFtZTp0LGFyZ3M6ZX0pfSk7dmFyIHA9bmV3IE1hcDtzZWxmLnJlcXVpcmU9dD0+e2xldCBlPXAuZ2V0KHQpO2lmKCFlKXRocm93IG5ldyBFcnJvcihgRHluYW1pY2FsbHkgaW1wb3J0aW5nIG5vbi1wcmVsb2FkZWQgbGlicmFyeSAke3R9YCk7cmV0dXJuIGV9O3NlbGYuY29uc29sZT1uZXcgYSgodCxlKT0+e28oe3R5cGU6ImxvZyIsbGV2ZWw6dCxtZXNzYWdlOmV9KX0sITEpO2Z1bmN0aW9uIGgodCl7cmV0dXJuYHJldHVybiAoJHt0fSlbImRlZmF1bHQiXWB9c2VsZi5hZGRFdmVudExpc3RlbmVyKCJtZXNzYWdlIix0PT57bChhc3luYygpPT57bGV0IGU9dC5kYXRhO3N3aXRjaChlLnR5cGUpe2Nhc2UibG9hZCI6e2xldCBuPW5ldyBGdW5jdGlvbihoKGUuY29kZSkpO2cuc2V0KGUubmFtZSxuKCkpLG8oe3R5cGU6ImluaXRlZCIsbmFtZTplLm5hbWV9KX1icmVhaztjYXNlImxvYWQtZGVwZW5kZW5jeSI6e2xldCByPW5ldyBGdW5jdGlvbihgcmV0dXJuICR7ZS5jb2RlfWApKCk7cC5zZXQoZS5uYW1lLHIpLG8oe3R5cGU6ImRlcGVuZGVuY3ktaW5pdGVkIixuYW1lOmUubmFtZX0pfWJyZWFrO2Nhc2UiaW52b2tlIjp7bGV0IG49Zy5nZXQoZS5uYW1lKTtpZighbil0aHJvdyBuZXcgRXJyb3IoYEZ1bmN0aW9uIG5vdCBsb2FkZWQ6ICR7ZS5uYW1lfWApO3RyeXtsZXQgcj1hd2FpdCBQcm9taXNlLnJlc29sdmUobiguLi5lLmFyZ3N8fFtdKSk7byh7dHlwZToicmVzdWx0IixpZDplLmlkLHJlc3VsdDpyfSl9Y2F0Y2gocil7byh7dHlwZToicmVzdWx0IixpZDplLmlkLGVycm9yOnIubWVzc2FnZSxzdGFjazpyLnN0YWNrfSl9fWJyZWFrO2Nhc2Uic3lzY2FsbC1yZXNwb25zZSI6e2xldCBuPWUuaWQscj1pLmdldChuKTtpZighcil0aHJvdyBjb25zb2xlLmxvZygiQ3VycmVudCBvdXRzdGFuZGluZyByZXF1ZXN0cyIsaSwibG9va2luZyB1cCIsbiksRXJyb3IoIkludmFsaWQgcmVxdWVzdCBpZCIpO2kuZGVsZXRlKG4pLGUuZXJyb3I/ci5yZWplY3QobmV3IEVycm9yKGUuZXJyb3IpKTpyLnJlc29sdmUoZS5yZXN1bHQpfWJyZWFrfX0pfSk7dSgpO30pKCk7CiByZXR1cm4gbW9kO30pKCk="
|
||||
}
|
|
@ -9,7 +9,7 @@ export class Plug<HookT> {
|
|||
public manifest?: Manifest<HookT>;
|
||||
public assets?: AssetBundle;
|
||||
private sandboxFactory: (plug: Plug<HookT>) => Sandbox;
|
||||
readonly runtimeEnv: RuntimeEnvironment;
|
||||
readonly runtimeEnv?: RuntimeEnvironment;
|
||||
grantedPermissions: string[] = [];
|
||||
name: string;
|
||||
version: number;
|
||||
|
@ -23,7 +23,7 @@ export class Plug<HookT> {
|
|||
this.name = name;
|
||||
this.sandboxFactory = sandboxFactory;
|
||||
// this.sandbox = sandboxFactory(this);
|
||||
this.runtimeEnv = system.runtimeEnv;
|
||||
this.runtimeEnv = system.env;
|
||||
this.version = new Date().getTime();
|
||||
}
|
||||
|
||||
|
@ -69,7 +69,7 @@ export class Plug<HookT> {
|
|||
if (!funDef) {
|
||||
throw new Error(`Function ${name} not found in manifest`);
|
||||
}
|
||||
return !funDef.env || funDef.env === this.runtimeEnv;
|
||||
return !funDef.env || !this.runtimeEnv || funDef.env === this.runtimeEnv;
|
||||
}
|
||||
|
||||
async invoke(name: string, args: any[]): Promise<any> {
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
import { AssetBundle } from "../asset_bundle/bundle.ts";
|
||||
import { ISQLite } from "./sqlite_interface.ts";
|
||||
import workerBundleJson from "./worker_bundle.json" assert { type: "json" };
|
||||
|
||||
const workerBundle = new AssetBundle(workerBundleJson);
|
||||
|
||||
export class AsyncSQLite {
|
||||
export class AsyncSQLite implements ISQLite {
|
||||
worker: Worker;
|
||||
requestId = 0;
|
||||
outstandingRequests = new Map<
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
import { Capacitor } from "../../mobile/deps.ts";
|
||||
import { CapacitorSQLite } from "../deps.ts";
|
||||
import { ISQLite } from "./sqlite_interface.ts";
|
||||
|
||||
export class CapacitorDb implements ISQLite {
|
||||
constructor(readonly name: string) {
|
||||
}
|
||||
async init() {
|
||||
await CapacitorSQLite.createConnection({
|
||||
database: this.name,
|
||||
});
|
||||
await CapacitorSQLite.open({
|
||||
database: this.name,
|
||||
});
|
||||
}
|
||||
|
||||
async query(sql: string, ...args: any[]) {
|
||||
const result = await CapacitorSQLite.query({
|
||||
statement: sql,
|
||||
database: this.name,
|
||||
values: args,
|
||||
});
|
||||
if (Capacitor.getPlatform() === "ios") {
|
||||
return result.values!.slice(1);
|
||||
}
|
||||
return result.values!;
|
||||
}
|
||||
|
||||
async execute(sql: string, ...args: any[]): Promise<number> {
|
||||
return (await CapacitorSQLite.run({
|
||||
statement: sql,
|
||||
database: this.name,
|
||||
values: args,
|
||||
})).changes!.changes!;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
export interface ISQLite {
|
||||
execute(query: string, ...params: any[]): Promise<number>;
|
||||
query(query: string, ...params: any[]): Promise<any[]>;
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
import type {
|
||||
SandboxFetchRequest,
|
||||
SandboxFetchResponse,
|
||||
} from "../../plug-api/plugos-syscall/fetch.ts";
|
||||
import { base64Encode } from "../asset_bundle/base64.ts";
|
||||
import { SysCallMapping } from "../system.ts";
|
||||
|
||||
export async function sandboxFetch(
|
||||
url: string,
|
||||
req?: SandboxFetchRequest,
|
||||
): Promise<SandboxFetchResponse> {
|
||||
const result = await fetch(
|
||||
url,
|
||||
req && {
|
||||
method: req.method,
|
||||
headers: req.headers,
|
||||
},
|
||||
);
|
||||
const body = await (await result.blob()).arrayBuffer();
|
||||
return {
|
||||
ok: result.ok,
|
||||
status: result.status,
|
||||
headers: Object.fromEntries(result.headers.entries()),
|
||||
base64Body: base64Encode(new Uint8Array(body)),
|
||||
};
|
||||
}
|
||||
|
||||
export function sandboxFetchSyscalls(): SysCallMapping {
|
||||
return {
|
||||
"sandboxFetch.fetch": (
|
||||
_ctx,
|
||||
url: string,
|
||||
options?: SandboxFetchRequest,
|
||||
): Promise<SandboxFetchResponse> => {
|
||||
return sandboxFetch(url, options);
|
||||
},
|
||||
};
|
||||
}
|
|
@ -1,9 +1,9 @@
|
|||
import { FullTextSearchOptions } from "../../plug-api/plugos-syscall/fulltext.ts";
|
||||
import { AsyncSQLite } from "../../plugos/sqlite/async_sqlite.ts";
|
||||
import { ISQLite } from "../sqlite/sqlite_interface.ts";
|
||||
import { SysCallMapping } from "../system.ts";
|
||||
|
||||
export async function ensureFTSTable(
|
||||
db: AsyncSQLite,
|
||||
db: ISQLite,
|
||||
tableName: string,
|
||||
) {
|
||||
const result = await db.query(
|
||||
|
@ -20,7 +20,7 @@ export async function ensureFTSTable(
|
|||
}
|
||||
|
||||
export function fullTextSearchSyscalls(
|
||||
db: AsyncSQLite,
|
||||
db: ISQLite,
|
||||
tableName: string,
|
||||
): SysCallMapping {
|
||||
return {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { assertEquals } from "../../test_deps.ts";
|
||||
import { createSandbox } from "../environments/deno_sandbox.ts";
|
||||
import { System } from "../system.ts";
|
||||
import { ensureTable, storeSyscalls } from "./store.deno.ts";
|
||||
import { ensureTable, storeSyscalls } from "./store.sqlite.ts";
|
||||
import { AsyncSQLite } from "../sqlite/async_sqlite.ts";
|
||||
|
||||
Deno.test("Test store", async () => {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { AsyncSQLite } from "../sqlite/async_sqlite.ts";
|
||||
import { ISQLite } from "../sqlite/sqlite_interface.ts";
|
||||
import { SysCallMapping } from "../system.ts";
|
||||
|
||||
export type Item = {
|
||||
|
@ -12,7 +12,7 @@ export type KV = {
|
|||
value: any;
|
||||
};
|
||||
|
||||
export async function ensureTable(db: AsyncSQLite, tableName: string) {
|
||||
export async function ensureTable(db: ISQLite, tableName: string) {
|
||||
const result = await db.query(
|
||||
`SELECT name FROM sqlite_master WHERE type='table' AND name=?`,
|
||||
tableName,
|
||||
|
@ -72,7 +72,7 @@ export function queryToSql(
|
|||
}
|
||||
|
||||
export function storeSyscalls(
|
||||
db: AsyncSQLite,
|
||||
db: ISQLite,
|
||||
tableName: string,
|
||||
): SysCallMapping {
|
||||
const apiObj: SysCallMapping = {
|
|
@ -30,14 +30,12 @@ type Syscall = {
|
|||
};
|
||||
|
||||
export class System<HookT> extends EventEmitter<SystemEvents<HookT>> {
|
||||
readonly runtimeEnv: RuntimeEnvironment;
|
||||
protected plugs = new Map<string, Plug<HookT>>();
|
||||
protected registeredSyscalls = new Map<string, Syscall>();
|
||||
protected enabledHooks = new Set<Hook<HookT>>();
|
||||
|
||||
constructor(env: RuntimeEnvironment) {
|
||||
constructor(readonly env?: RuntimeEnvironment) {
|
||||
super();
|
||||
this.runtimeEnv = env;
|
||||
}
|
||||
|
||||
get loadedPlugs(): Map<string, Plug<HookT>> {
|
||||
|
|
|
@ -6,6 +6,8 @@ import { renderToText, replaceNodesMatching } from "$sb/lib/tree.ts";
|
|||
import type { FileMeta } from "../../common/types.ts";
|
||||
import { parseMarkdown } from "$sb/silverbullet-syscall/markdown.ts";
|
||||
import { base64EncodedDataUrl } from "../../plugos/asset_bundle/base64.ts";
|
||||
import { CapacitorHttp } from "@capacitor/core";
|
||||
import { sandboxFetch } from "../../plug-api/plugos-syscall/fetch.ts";
|
||||
|
||||
const pagePrefix = "💭 ";
|
||||
|
||||
|
@ -27,15 +29,16 @@ export async function readFileCloud(
|
|||
url = `http://${url}`;
|
||||
}
|
||||
let text = "";
|
||||
|
||||
try {
|
||||
const r = await fetch(`${url}.md`);
|
||||
text = await r.text();
|
||||
if (r.status !== 200) {
|
||||
if (!r.ok) {
|
||||
text = `ERROR: ${text}`;
|
||||
}
|
||||
} catch (e: any) {
|
||||
console.error("ERROR", e.message);
|
||||
text = e.message;
|
||||
console.error("ERROR thrown", e.message);
|
||||
text = `ERROR: ${e.message}`;
|
||||
}
|
||||
text = await translateLinksWithPrefix(
|
||||
text,
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
This page contains settings for configuring SilverBullet and its plugs. Any
|
||||
changes outside of the yaml block will be overwritten.
|
||||
|
||||
```yaml
|
||||
indexPage: index
|
||||
```
|
|
@ -12,7 +12,7 @@ export class PlugSpacePrimitives implements SpacePrimitives {
|
|||
constructor(
|
||||
private wrapped: SpacePrimitives,
|
||||
private hook: PageNamespaceHook,
|
||||
private env: string,
|
||||
private env?: string,
|
||||
) {}
|
||||
|
||||
performOperation(
|
||||
|
@ -25,7 +25,7 @@ export class PlugSpacePrimitives implements SpacePrimitives {
|
|||
) {
|
||||
if (
|
||||
operation === type && pageName.match(pattern) &&
|
||||
(env ? env === this.env : true)
|
||||
(!this.env || (env && env === this.env))
|
||||
) {
|
||||
return plug.invoke(name, [pageName, ...args]);
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ import { SpacePrimitives } from "../common/spaces/space_primitives.ts";
|
|||
import { EndpointHook } from "../plugos/hooks/endpoint.ts";
|
||||
import { AssetBundle } from "../plugos/asset_bundle/bundle.ts";
|
||||
import { SpaceSystem } from "./space_system.ts";
|
||||
import { parseYamlSettings } from "../common/util.ts";
|
||||
import { ensureAndLoadSettings } from "../common/util.ts";
|
||||
|
||||
export type ServerOptions = {
|
||||
hostname: string;
|
||||
|
@ -66,7 +66,7 @@ export class HttpServer {
|
|||
async start() {
|
||||
await this.systemBoot.start();
|
||||
await this.systemBoot.ensureSpaceIndex();
|
||||
await this.ensureAndLoadSettings();
|
||||
await ensureAndLoadSettings(this.systemBoot.space);
|
||||
|
||||
this.addPasswordAuth(this.app);
|
||||
|
||||
|
@ -149,34 +149,6 @@ export class HttpServer {
|
|||
);
|
||||
}
|
||||
|
||||
async ensureAndLoadSettings() {
|
||||
const space = this.systemBoot.space;
|
||||
try {
|
||||
await space.getPageMeta("SETTINGS");
|
||||
} catch {
|
||||
await space.writePage(
|
||||
"SETTINGS",
|
||||
this.systemBoot.assetBundle.readTextFileSync("SETTINGS_template.md"),
|
||||
true,
|
||||
);
|
||||
}
|
||||
|
||||
const { text: settingsText } = await space.readPage("SETTINGS");
|
||||
const settings = parseYamlSettings(settingsText);
|
||||
if (!settings.indexPage) {
|
||||
settings.indexPage = "index";
|
||||
}
|
||||
|
||||
try {
|
||||
await space.getPageMeta(settings.indexPage);
|
||||
} catch {
|
||||
await space.writePage(
|
||||
settings.indexPage,
|
||||
`Welcome to your new space!`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private addPasswordAuth(app: Application) {
|
||||
const excludedPaths = [
|
||||
"/manifest.json",
|
||||
|
|
|
@ -21,7 +21,7 @@ import shellSyscalls from "../plugos/syscalls/shell.deno.ts";
|
|||
import {
|
||||
ensureTable as ensureStoreTable,
|
||||
storeSyscalls,
|
||||
} from "../plugos/syscalls/store.deno.ts";
|
||||
} from "../plugos/syscalls/store.sqlite.ts";
|
||||
import { System } from "../plugos/system.ts";
|
||||
import { PageNamespaceHook } from "./hooks/page_namespace.ts";
|
||||
import { PlugSpacePrimitives } from "./hooks/plug_space_primitives.ts";
|
||||
|
@ -36,6 +36,7 @@ import assetSyscalls from "../plugos/syscalls/asset.ts";
|
|||
import { AssetBundle } from "../plugos/asset_bundle/bundle.ts";
|
||||
import { AsyncSQLite } from "../plugos/sqlite/async_sqlite.ts";
|
||||
import { FileMetaSpacePrimitives } from "../common/spaces/file_meta_space_primitives.ts";
|
||||
import { sandboxFetchSyscalls } from "../plugos/syscalls/fetch.ts";
|
||||
export const indexRequiredKey = "$spaceIndexed";
|
||||
|
||||
// A composition of a PlugOS system attached to a Space for server-side use
|
||||
|
@ -116,6 +117,7 @@ export class SpaceSystem {
|
|||
systemSyscalls(this.loadPlugsFromSpace.bind(this), this.system),
|
||||
sandboxSyscalls(this.system),
|
||||
assetSyscalls(this.system),
|
||||
sandboxFetchSyscalls(),
|
||||
);
|
||||
|
||||
// Danger zone, these syscalls require requesting specific permissions
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// import { Knex } from "knex";
|
||||
import { SysCallMapping } from "../../plugos/system.ts";
|
||||
import { Query, queryToSql } from "../../plugos/syscalls/store.deno.ts";
|
||||
import { AsyncSQLite } from "../../plugos/sqlite/async_sqlite.ts";
|
||||
import { Query, queryToSql } from "../../plugos/syscalls/store.sqlite.ts";
|
||||
import { ISQLite } from "../../plugos/sqlite/sqlite_interface.ts";
|
||||
|
||||
type Item = {
|
||||
page: string;
|
||||
|
@ -16,7 +16,7 @@ export type KV = {
|
|||
|
||||
const tableName = "page_index";
|
||||
|
||||
export async function ensureTable(db: AsyncSQLite): Promise<void> {
|
||||
export async function ensureTable(db: ISQLite): Promise<void> {
|
||||
const result = await db.query(
|
||||
`SELECT name FROM sqlite_master WHERE type='table' AND name=?`,
|
||||
tableName,
|
||||
|
@ -32,7 +32,7 @@ export async function ensureTable(db: AsyncSQLite): Promise<void> {
|
|||
}
|
||||
}
|
||||
|
||||
export function pageIndexSyscalls(db: AsyncSQLite): SysCallMapping {
|
||||
export function pageIndexSyscalls(db: ISQLite): SysCallMapping {
|
||||
const apiObj: SysCallMapping = {
|
||||
"index.set": async (_ctx, page: string, key: string, value: any) => {
|
||||
await db.execute(
|
||||
|
|
20
web/boot.ts
20
web/boot.ts
|
@ -7,6 +7,12 @@ import { PageNamespaceHook } from "../server/hooks/page_namespace.ts";
|
|||
import { SilverBulletHooks } from "../common/manifest.ts";
|
||||
import { System } from "../plugos/system.ts";
|
||||
import { BuiltinSettings } from "./types.ts";
|
||||
import { fulltextSyscalls } from "./syscalls/fulltext.ts";
|
||||
import { indexerSyscalls } from "./syscalls/index.ts";
|
||||
import { storeSyscalls } from "./syscalls/store.ts";
|
||||
import { EventHook } from "../plugos/hooks/event.ts";
|
||||
import { clientStoreSyscalls } from "./syscalls/clientStore.ts";
|
||||
import { sandboxFetchSyscalls } from "./syscalls/fetch.ts";
|
||||
|
||||
safeRun(async () => {
|
||||
const httpPrimitives = new HttpSpacePrimitives("");
|
||||
|
@ -35,6 +41,16 @@ safeRun(async () => {
|
|||
const serverSpace = new Space(spacePrimitives);
|
||||
serverSpace.watch();
|
||||
|
||||
// Register some web-specific syscall implementations
|
||||
system.registerSyscalls(
|
||||
[],
|
||||
storeSyscalls(serverSpace),
|
||||
indexerSyscalls(serverSpace),
|
||||
clientStoreSyscalls(),
|
||||
fulltextSyscalls(serverSpace),
|
||||
sandboxFetchSyscalls(serverSpace),
|
||||
);
|
||||
|
||||
console.log("Booting...");
|
||||
|
||||
const settings = parseYamlSettings(settingsPageText) as BuiltinSettings;
|
||||
|
@ -42,10 +58,14 @@ safeRun(async () => {
|
|||
if (!settings.indexPage) {
|
||||
settings.indexPage = "index";
|
||||
}
|
||||
// Event hook
|
||||
const eventHook = new EventHook();
|
||||
system.addHook(eventHook);
|
||||
|
||||
const editor = new Editor(
|
||||
serverSpace,
|
||||
system,
|
||||
eventHook,
|
||||
document.getElementById("sb-root")!,
|
||||
"",
|
||||
settings,
|
||||
|
|
|
@ -7,8 +7,14 @@ import {
|
|||
} from "../deps.ts";
|
||||
import { decoratorStateField } from "./util.ts";
|
||||
|
||||
import type { Space } from "../../common/spaces/space.ts";
|
||||
|
||||
class InlineImageWidget extends WidgetType {
|
||||
constructor(readonly url: string, readonly title: string) {
|
||||
constructor(
|
||||
readonly url: string,
|
||||
readonly title: string,
|
||||
readonly space: Space,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
|
@ -21,8 +27,14 @@ class InlineImageWidget extends WidgetType {
|
|||
if (this.url.startsWith("http")) {
|
||||
img.src = this.url;
|
||||
} else {
|
||||
img.src = `fs/${this.url}`;
|
||||
// Specific to mobile
|
||||
this.space.readAttachment(decodeURI(this.url), "dataurl").then(
|
||||
({ data }) => {
|
||||
img.src = data as string;
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
img.alt = this.title;
|
||||
img.title = this.title;
|
||||
img.style.display = "block";
|
||||
|
@ -32,7 +44,7 @@ class InlineImageWidget extends WidgetType {
|
|||
}
|
||||
}
|
||||
|
||||
export function inlineImagesPlugin() {
|
||||
export function inlineImagesPlugin(space: Space) {
|
||||
return decoratorStateField((state: EditorState) => {
|
||||
const widgets: Range<Decoration>[] = [];
|
||||
const imageRegex = /!\[(?<title>[^\]]*)\]\((?<url>.+)\)/;
|
||||
|
@ -54,7 +66,7 @@ export function inlineImagesPlugin() {
|
|||
const title = imageRexexResult.groups.title;
|
||||
widgets.push(
|
||||
Decoration.widget({
|
||||
widget: new InlineImageWidget(url, title),
|
||||
widget: new InlineImageWidget(url, title, space),
|
||||
}).range(node.to),
|
||||
);
|
||||
},
|
||||
|
|
|
@ -24,6 +24,7 @@ import {
|
|||
markdown,
|
||||
runScopeHandlers,
|
||||
searchKeymap,
|
||||
sqlLanguage,
|
||||
standardKeymap,
|
||||
StreamLanguage,
|
||||
syntaxHighlighting,
|
||||
|
@ -32,7 +33,6 @@ import {
|
|||
ViewPlugin,
|
||||
ViewUpdate,
|
||||
yamlLanguage,
|
||||
sqlLanguage,
|
||||
} from "../common/deps.ts";
|
||||
import { SilverBulletHooks } from "../common/manifest.ts";
|
||||
import {
|
||||
|
@ -96,6 +96,7 @@ import type {
|
|||
CompleteEvent,
|
||||
} from "../plug-api/app_event.ts";
|
||||
import { CodeWidgetHook } from "./hooks/code_widget.ts";
|
||||
import { sandboxFetchSyscalls } from "../plugos/syscalls/fetch.ts";
|
||||
|
||||
const frontMatterRegex = /^---\n(.*?)---\n/ms;
|
||||
|
||||
|
@ -139,6 +140,7 @@ export class Editor {
|
|||
constructor(
|
||||
space: Space,
|
||||
system: System<SilverBulletHooks>,
|
||||
eventHook: EventHook,
|
||||
parent: Element,
|
||||
urlPrefix: string,
|
||||
readonly builtinSettings: BuiltinSettings,
|
||||
|
@ -150,9 +152,7 @@ export class Editor {
|
|||
this.viewDispatch = () => {};
|
||||
this.indexPage = builtinSettings.indexPage;
|
||||
|
||||
// Event hook
|
||||
this.eventHook = new EventHook();
|
||||
this.system.addHook(this.eventHook);
|
||||
this.eventHook = eventHook;
|
||||
|
||||
// Code widget hook
|
||||
this.codeWidgetHook = new CodeWidgetHook();
|
||||
|
@ -191,12 +191,8 @@ export class Editor {
|
|||
eventSyscalls(this.eventHook),
|
||||
editorSyscalls(this),
|
||||
spaceSyscalls(this),
|
||||
indexerSyscalls(this.space),
|
||||
fulltextSyscalls(this.space),
|
||||
systemSyscalls(this, this.system),
|
||||
markdownSyscalls(buildMarkdown(this.mdExtensions)),
|
||||
clientStoreSyscalls(),
|
||||
storeSyscalls(this.space),
|
||||
sandboxSyscalls(this.system),
|
||||
assetSyscalls(this.system),
|
||||
collabSyscalls(this),
|
||||
|
@ -484,6 +480,7 @@ export class Editor {
|
|||
}
|
||||
// deno-lint-ignore no-this-alias
|
||||
const editor = this;
|
||||
let touchCount = 0;
|
||||
|
||||
return EditorState.create({
|
||||
doc: this.collabState ? this.collabState.ytext.toString() : text,
|
||||
|
@ -528,7 +525,7 @@ export class Editor {
|
|||
),
|
||||
],
|
||||
}),
|
||||
inlineImagesPlugin(),
|
||||
inlineImagesPlugin(this.space),
|
||||
highlightSpecialChars(),
|
||||
history(),
|
||||
drawSelection(),
|
||||
|
@ -601,6 +598,29 @@ export class Editor {
|
|||
},
|
||||
]),
|
||||
EditorView.domEventHandlers({
|
||||
// This may result in duplicated touch events on mobile devices
|
||||
touchmove: (event: TouchEvent, view: EditorView) => {
|
||||
touchCount++;
|
||||
},
|
||||
touchend: (event: TouchEvent, view: EditorView) => {
|
||||
if (touchCount === 0) {
|
||||
safeRun(async () => {
|
||||
const touch = event.changedTouches.item(0)!;
|
||||
const clickEvent: ClickEvent = {
|
||||
page: pageName,
|
||||
ctrlKey: event.ctrlKey,
|
||||
metaKey: event.metaKey,
|
||||
altKey: event.altKey,
|
||||
pos: view.posAtCoords({
|
||||
x: touch.clientX,
|
||||
y: touch.clientY,
|
||||
})!,
|
||||
};
|
||||
await this.dispatchAppEvent("page:click", clickEvent);
|
||||
});
|
||||
}
|
||||
touchCount = 0;
|
||||
},
|
||||
click: (event: MouseEvent, view: EditorView) => {
|
||||
safeRun(async () => {
|
||||
const clickEvent: ClickEvent = {
|
||||
|
@ -1011,6 +1031,7 @@ export class Editor {
|
|||
description: `Open page (${isMacLike() ? "Cmd-k" : "Ctrl-k"})`,
|
||||
callback: () => {
|
||||
dispatch({ type: "start-navigate" });
|
||||
this.space.updatePageList();
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
|
@ -1,43 +1,47 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<base href="/" />
|
||||
|
||||
<title>Silver Bullet</title>
|
||||
<script>
|
||||
Deno = {
|
||||
args: [],
|
||||
build: {
|
||||
arch: "x86_64",
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<base href="/" />
|
||||
|
||||
<title>Silver Bullet</title>
|
||||
<script>
|
||||
Deno = {
|
||||
args: [],
|
||||
build: {
|
||||
arch: "x86_64",
|
||||
},
|
||||
env: {
|
||||
get(key) {
|
||||
// return undefined;
|
||||
},
|
||||
env: {
|
||||
get(key) {
|
||||
// return undefined;
|
||||
},
|
||||
},
|
||||
errors: {
|
||||
AlreadyExists: class extends Error {},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style>
|
||||
html,
|
||||
body {
|
||||
margin: 0;
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
},
|
||||
errors: {
|
||||
AlreadyExists: class extends Error { },
|
||||
}
|
||||
</style>
|
||||
<link rel="stylesheet" href="/main.css" />
|
||||
<script type="module" src="/client.js"></script>
|
||||
<link rel="manifest" href="/manifest.json" -->
|
||||
<link rel="icon" type="image/x-icon" href="/favicon.png" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="sb-root"></div>
|
||||
</body>
|
||||
</html>
|
||||
};
|
||||
</script>
|
||||
<style>
|
||||
html,
|
||||
body {
|
||||
margin: 0;
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
<link rel="stylesheet" href="/main.css" />
|
||||
<script type="module" src="/client.js"></script>
|
||||
<link rel="manifest" href="/manifest.json" />
|
||||
<link rel="icon" type="image/x-icon" href="/favicon.png" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="sb-root"></div>
|
||||
<h1>SUPPP</h1>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -0,0 +1,12 @@
|
|||
import type { SysCallMapping } from "../../plugos/system.ts";
|
||||
import { proxySyscalls } from "../../plugos/syscalls/transport.ts";
|
||||
import type { Space } from "../../common/spaces/space.ts";
|
||||
|
||||
export function sandboxFetchSyscalls(space: Space): SysCallMapping {
|
||||
return proxySyscalls(
|
||||
[
|
||||
"sandboxFetch.fetch",
|
||||
],
|
||||
(ctx, name, ...args) => space.proxySyscall(ctx.plug, name, args),
|
||||
);
|
||||
}
|
|
@ -2,12 +2,18 @@ An attempt at documenting the changes/new features introduced in each
|
|||
release.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Next
|
||||
|
||||
* New {[Extract text to new page]} command
|
||||
* Improvement to listify commands by [Tristan Sokol](https://github.com/silverbulletmd/silverbullet/pull/290)
|
||||
* {[Extract text to new page]} command by [Tristan Sokol](https://github.com/silverbulletmd/silverbullet/pull/286)
|
||||
* SQL syntax highlighting in fenced code blocks by [Martin Kraft](https://github.com/silverbulletmd/silverbullet/pull/292)
|
||||
```sql
|
||||
select * from my_table;
|
||||
```
|
||||
* Merged code for experimental mobile app (iOS only for now)
|
||||
|
||||
---
|
||||
|
||||
|
|
Loading…
Reference in New Issue