-
Notifications
You must be signed in to change notification settings - Fork 2
Home
class Collection:
"""
.. describe:: count
Number of items in the collection (that are not trashed).
"""
def __init__(self, host, meta):
# ...
self.count = meta['count']
self.author_ids = meta['author_ids']
@property
def authors(self):
return self.app.r.omget(self._author_ids)
def add(self, item):
"""Subclass API."""
self.app.r.rpush(self.map_key, item.id)
self._update()
def json(self, restricted=False, include=False):
return {
'count': self.count,
**{'author_ids': self._author_ids},
**({'authors': [a.json(restricted, include) for a in self.authors]} if include else {})
}
def _update(self):
active = [item for item in self.values() if not item.trashed]
self.count = len(active)
self.author_ids = list(set(author.id for item in active for author in item.authors))
self.app.r.oset(self.host[0].id, self.host[0])
class Trashable:
def __init__(self, trashed, collection=None, activity=None):
# ...
self.__collection = collection
def trash(self):
# ...
if self.__collection:
self.__collection._update()
def restore(self):
# ...
if self.__collection:
self.__collection._update()
Object.assign(this.eventTemplates, {
"purr": ".foo-purr-event-template"
});
this.eventData = {makeURL: foo.makeURL};
let elem = document.importNode(ui.querySelector(ui.eventTemplates[event.type]).content, true);
micro.bind.bind(elem, Object.assign({event}, this.eventData));
li.appendChild(elem);
- MVP / Beta 1:
- Target: App is usable in a minimal form. User mistakes are correctable.
- Audience: Groups the developers are themselves part of
- Feedback channel: Direct
- Beta 2:
- Target: App is usable on a daily basis. Core functionality is implemented. Purpose is clearly apparent to first time users. Feedback from Beta 1 is incorporated.
- Audience: Social networks of the developers
- Feedback channel: Social networks / App
- Beta 3:
- Target: App monitoring is available. Feedback from Beta 2 is incorporated.
- Audience: Public, announced on various platforms, e.g.:
- Feedback channel: App / Platforms
- Stable:
- Target: Features expected from a self-contained app are implemented. Feedback from Beta 3 is incorporated.
unwatch(prop, onUpdate) {
let i = (watchers[prop] || []).findIndex(f => f === onUpdate);
if (i === -1) {
throw new Error();
}
watchers.splice(i, 1);
}
Sophisticated user listing:
<p data-title="joinText list.authors ', ' map 'name'">
<span class="fa fa-pencil"></span>
<span data-content="join list.authors 'user' ', ' 3">
<template><micro-user></micro-user></template>
<template data-name="overflow">
+ <span data-content="sub list.authors.length 3"></span>
</template>
</span>
</p>
Switch:
<span data-content="switch user.role 'user' 'staff'">
<template><button>User action</button></template>
<template><button>Staff action</button></template>
<template>Nothing to do</template>
</span>
<span data-content="switch user.staff true">
<template><button>Staff action</button></template>
</span>
Format:
<span data-content="format 'Hello {user}!' 'user' user.name">
<span data-content="format 'Hello {user}!'">
<template name="user"><micro-user data-user="user"></micro-user></template>
</span>
Translate (calls format):
<span data-content="translate 'hello' 'user' user.name">
Advanced translation example:
<p>
<span data-content="translateEditedBy list.authors">
<template data-name="authors">
<span data-content="join list.authors 'user' ', ' 3">
<template><micro-user></micro-user></template>
</span>
</template>
</span>
</p>
<script>
this.data.translateEditedBy = (ctx, authors) => {
let n = authors.length;
return micro.bind.translate(ctx, n > 3 ? "edited-by-overflow" : "edited-by", "n", n);
}
{
"edited-by": "edited by {authors}",
"edited-by-overflow": ["edited by {authors} and {n} other", "edited by {authors} and {n} others"]
}
</script>
- Python / JavaScript API:
- Breaking changes okay
- User decides update time
- Sometimes non-breaking changes are not possible or only with disproportionate effort:
- (JavaScript) Convert
<custom-element>
from/to<div is="custom-element">
(can only be registered once)
- (JavaScript) Convert
- Web API:
- Breaking changes only after deprecation period
- Service provider decides update time, user needs time to make adjustments
Idea for non-breaking update path for function signatures:
def foo(a, b):
# ...
# ->
def foo(a, x, b=None, __version__=1):
if __version__ == 1:
b, x = x, 'default'
else:
if b is None:
raise Error()
# ...
# ->
def foo(a, x, b, __version__=2):
# ...
Assume that micro introduces a new announcement feature with the following API:
- type
Announcement
- Attribute
Application.announcements
- DB key
announcements
- endpoint
/api/announcements
- page
/announcements
- ...
If an existing micro application already makes use of any of those names, this could lead to breaking behavior (e.g. micro code modifies Application.announcements
or posts to /api/announcements
and they have different, unexpected semantics).
How can we solve this? New features that involve the extendable API could be major releases. New features could be introduced behind a feature toggle with a minor release and enabled by default with a major release. DB keys could be prefixed with micro
.
Rules that may be worth considering:
- multiline-comment-style (ESLint 4.9)