ZineOS User's Guide
So you've discovered the ancient wisdom and followed the light to ZineOS. You may be wondering, what is this place? How do I program things? How do I use ZineOS? What are the APIs? All these questions and more will be answered in this guide!
Desktop Operating System Basics
Right click on the desktop to create a file! Tough luck if you're on mobile, mobile support ComingSoonTM.
Drag and drop files from your local PC into ZineOS to copy them there. Images, audio, text, it's all gravy!
You can run an app by double clickng or open a text, image, audio, or code file. Right click on an item to open the context menu.
You can explore the zines and applications in the start menu at the bottom left.
Save files to The Cloud with "My Briefcase" or in this case, your briefcase.
Drag files and drop them on or in folders to move them around and organize the zine to match YOUR experience.
Application Basics
Applications in ZineOS are very simple to get started with. Easy to learn, a lifetime to master. Remeber kids, the computer revolution starts with YOU!
Give a man a program, frustrate him for a day.
Teach a man to program, frustrate him for a lifetime.― Muhammad Waseem
Your First Application
Create a new file in ZineOS. Name it main.js
. Inside that file:
// Sample App 1 - Your First Application
alert('hello world');
Run your app. You will see a window pop up, then an alert pop up. Close the alert and close the window. You've successfully written your first app!
The DOM
Your app window includes a sandboxed HTML DOM. Everything you know about HTML applies to ZineOS apps. The only difference is that if your app is a .js file you'll interact with the DOM through JavaScript rather than writing out HTML.
// Sample App 2 - The DOM
document.body.style.backgroundColor = "red";
var h1 = document.createElement('h1');
h1.innerText = "Hello World";
document.body.appendChild(h1);
Multiple Files
You can require other files to split up your code in whatever way makes sense.
Whatever is assigned to module.exports
is returned in the call to require
.
Paths are relative to the file calling require
. You can even require
other
files that are deep inside folders like the ancient explorers of old.
// Sample App 3 - Multiple Files
// main.js
var message = require("./message"); // Note: no file extension
alert(message);
// message.js
module.exports = "Hello from another world!";
Interacting with ZineOS
You can read files from the system, check it:
// main.js
system.readFile("./main.js")
.then(console.log);
This app reads itself from the file system and displays that to the console.
Application Communication
Spawn an app and send messages to it!
// sender.js
application.title("Sender");
system.launchAppByPath("./receiver.js").then(function({id}) {
application.title("Sender - Receiver Id is " + id);
system.tell(id, "append", "hello");
document.addEventListener("click", function(e) {
system.tell(id, "append", `${e.pageX},${e.pageY}`);
});
});
// receiver.js
var pre = document.createElement('pre');
document.body.appendChild(pre);
application.title("Receiver");
application.delegate = {
append: function(item) {
pre.innerText += item + "\n";
}
};
App Interaction APIs
The system has these methods for interacting with other apps.
kill: (appId) ->
tell: (appId, type, message) ->
Extensions
We've extended some of the DOM APIs to make things easier for us.
system.readFile("./main.js")
.then(function(blob) {
blob.readAsText();
}).then(console.log);
Blob
readAsText: ([encoding]) -> Promise(String | Error)
getURL: -> URL ~ String
readAsJSON = -> Promise(JSON | Error)
readAsDataURL = -> Promise(URL ~ String | Error)
Image
Load an image from a blob returning a promise that is fulfilled with the loaded image or rejected with an error.
Image.fromBlob = (blob) -> Promise(Image | Error)
Pixie.cson
File System
These file system methods take a relative or absolute path and return promises. When you launch an app the paths are relative to the folder in which the app was launched. All of these methods return promises.
Methods
readFile: (path) -> Promise(Blob | Error)
readAsText: (path) -> Promise(String | Error)
readTree: (path) -> Promise(Array[FileEntry,FolderEntry] | Error)
writeFile: (path, blob) -> Promise
deleteFile: (path) -> Promise
Interfaces
FileEntry
interfacepath: String relativePath: String size: Number type: MimeType ~ String updatedAt: Timestamp ~ Number
FolderEntry
interfacefolder: true path: String
Events
Subscribe and trigger system events.
on: (type, handler) ->
off: (type, handler) ->
trigger: (type, data...) ->
You can also subscribe to all events with "*"
as the event type. In that case
the specific event type will be the first argument to your handler.
system.on("*", function(eventType, ...args) {
console.log(args);
});
system.trigger("cool", "rad", "dad");
// Will log ["rad", "dad"]
The system emits the following events:
- file
- read
- write
- list
- delete
- application
- start
- stop
Example Applications
Task Manager
// main.js
var Template, apps, selectedAppId, style;
style = document.createElement("style");
style.innerHTML = require("./style");
document.head.appendChild(style);
Template = require("./template");
selectedAppId = Observable(null);
apps = Observable([]);
application.title("Task Manager");
setInterval(function() {
return system.runningApplications().then(function(newApps) {
return apps(newApps);
});
}, 250);
document.body.appendChild(Template({
apps: apps,
selectedAppId: selectedAppId,
kill: function() {
return system.kill(selectedAppId());
}
}));
// template.jadelet
app
ul.tasks
- selectedAppId = @selectedAppId
- @apps.forEach (app) ->
- selected = "selected" if app.id is selectedAppId()
- select = -> selectedAppId app.id
li(class=selected mousedown=select)
.id= app.id
.title= app.title
actions
button(click=@kill) Kill
// style.styl
body
margin: 0
ul
margin: 0
padding: 0
li
user-select: none
display: flex
&:nth-child(2n)
background-color: #CCC
&.selected
background-color: #8F8
> .id
padding-left: 1rem
width: 50px
> .title
overflow: hidden
System Event Log
Open up this app and it will display a stream of all the system events going on.
// event-logger.js
application.title("System Event Log");
pre = document.createElement("pre");
document.body.appendChild(pre);
system.on("*", (...args) => {
pre.innerText += `${JSON.stringify(args)}\n`;
});
Application Message Debugger
You can drop a file on here and see what events fire :). Open the browser debugger and take a look.
// application-debugger.js
application.title(`Application Debugger [id: ${application.id}]`);
// Log any method call and arguments sent to the application delegate
application.delegate = new Proxy({}, {
get: (target, property, receiver) => {
return console.log.bind(console, property);
}
});