Gordon  Taylor

Gordon Taylor

1657128060

Encrypt-down: An Encryption Layer for LevelDB

🔐 encrypt-down 🔐

encrypt-down is an encryption layer for LevelDB.

For LevelDB exist several persistence bindings. Amongst others bindings for IndexedDB.

By using encrypt-down it is possible to store lots (several MB) of sensitive user data securely (encrypted) in the browser across user sessions.

Installation

npm install @adorsys/encrypt-down

Usage

We need a JSON Web Key (JWK) or JSON Web Key Set (JWKS) as specified by RFC 7517.

const memdown = require('memdown')
const encryptdown = require('@adorsys/encrypt-down')
const levelup = require('levelup')
const jwk = {
  kty: 'oct',
  alg: 'A256GCM',
  use: 'enc',
  k: '123456789abcdefghijklmnopqrstuvwxyz12345678'
}
const memdb = memdown()
const db = levelup(encryptdown(memdb, { jwk }))

db.put('key', { awesome: true }, function (err) {
  memdb._get('key', { asBuffer: false }, function (err, value) {
        console.log(value)
        // eyJlbmMiOiJBMjU2R0NNIiwiYWxnIjoiZGlyIiwia2lkIjoialpESEVqN0ZhR3N5OHNUSUZLRWlnejB4TjFEVWlBZWp0S1ZNcEl2Z3dqOCJ9..LLeRPtRCpn-Zie6-.zZc0LQ_vvHCppRAaC5fxw4yJ0041l6mGOSgLDVnaPagSv_3Khp8a8lyAo9utHQKpVX6RNVaVPBQQxJpkw_Zyljeg7L-O_Nc3N2Hi_904qE6_zwORqQRc.R0JhfgTHIcD_93kXzZ8BrA
  })
  db.get('key', { asBuffer: false }, function (err, value) {
    console.log(value) 
    // { awesome: true }
  })
})

Browser Support

Sauce Test Status

API

const db = require('@adorsys/encrypt-down')(db[, options])

  • db must be an abstract-leveldown compliant store
  • options:
    • jwk: a JSON Web Key (JWK) or JSON Web Key Set (JWKS) as specified by RFC 7517

Author: Adorsys
Source Code: https://github.com/adorsys/encrypt-down 
License: MIT license

#javascript #database #layers 

Encrypt-down: An Encryption Layer for LevelDB
Mike  Kozey

Mike Kozey

1656909180

Shindenshin: Layer Communication Package

Basics

This package includes all necessary basics to make comunications between UI, BL and Data layers.

Used dependencies:

  • dio
  • hive
  • bloc
  • equatable

ApiClient

This is a singleton class that contains basic REST methods and a little auth logic.

It should be initialized before used.

ApiClient inits itself automatically in Store constructor (see below).

init method has the following arguments:

  • releaseBaseHost - URI which will be used in release build;
  • forceUseReleaseHost - tells it to use release uri even in debug mode (default false);
  • androidDegubHost - URI for Android Emulator in debug mode (default 10.0.2.2)

BaseModel and BaseModalApi

These two are useful for mapping backend entities to your flutter application.

BaseModelApi can request a list (or paginatedList) of items, retreive a single item by id, create a new item and update or delete an existing one.

You should implement fromJson method and the url field which is a relative path (e.g. 'products', 'orders' etc.).

rootList parameter set to true is needed if response's data doesn't have a pagination.

BaseStore

Is needed to create a centralized Store which contains all the repositories.

BaseStore is Subscriptable so you can call subscribe(fn) and notify(event) methods to help repos communicate with each other.

BaseRepo

This class is needed to create your repositories. It's also Subscriptable.

All the repos should be initialized in Store's constructor and pass Store instance to super.

Installing

Use this package as a library

Depend on it

Run this command:

With Flutter:

 $ flutter pub add shindenshin

This will add a line like this to your package's pubspec.yaml (and run an implicit flutter pub get):

dependencies:
  shindenshin: ^0.1.10

Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.

Import it

Now in your Dart code, you can use:

import 'package:shindenshin/shindenshin.dart';

example/lib/main.dart

import 'package:example/cubit/app_navigator_cubit.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:shindenshin/shindenshin.dart';

import 'store/store.dart';
import 'views/main/main.dart';

void main() {
  runApp(const Application());
}

class Application extends StatefulWidget {
  const Application({Key? key}) : super(key: key);

  @override
  State<Application> createState() => _ApplicationState();
}

class _ApplicationState extends State<Application> {
  final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();

  late final BaseApiClient apiClient;
  late final Store store;

  @override
  void initState() {
    super.initState();

    final BaseOptions options = BaseOptions(
      baseUrl: 'https://example.com/api/v1/',
    );
    apiClient = BaseApiClient(Dio(options));
    store = Store(apiClient);
  }

  @override
  Widget build(BuildContext context) {
    return BlocProvider<AppNavigatorCubit>(
      create: (_) => AppNavigatorCubit(store),
      child: Main(
        store: store,
        navigatorKey: navigatorKey,
      ),
    );
  }
}

Author: justjew
Source Code: https://github.com/justjew/shindenshin 
License: MIT license

#flutter #dart #layers 

Shindenshin: Layer Communication Package
Hermann  Frami

Hermann Frami

1656554820

Serverless Ruby Layer

Serverless-ruby-layer

A Serverless Plugin which bundles ruby gems from Gemfile and deploys them to the lambda layer automatically while running serverless deploy.

It auto-configures the AWS lambda layer and RUBY_PATH to all the functions.

Install

Install ⚡️ serverless. Refer here for serverless installation instructions.

Navigate to your serverless project and install the plugin

sls plugin install -n serverless-ruby-layer

This will add the plugin to package.json and the plugins section of serverless.yml.

Getting Started

Simple Usage

serverless.yml

service: basic

plugins:
  - serverless-ruby-layer

provider:
  name: aws
  runtime: ruby2.5

functions:
  hello:
    handler: handler.hello

Gemfile

  source 'https://rubygems.org'
  gem 'httparty'

Running sls deploy automatically deploys the required gems as in Gemfile to AWS lambda layer and make the gems available to the RUBY_PATH of the functions hello.handler

Refer example amd docs for more details

Customization

The plugin operation can be customized by specifying the custom configuration under rubyLayer.

For example, to use docker environment for packing gem, the below configuration is added to serverless.yml

custom:
  rubyLayer:
    use_docker: true

For more detailse refer the docs here

Usage

Using the custom configuration, the plugin can be utilized for below cases,

  • Using locally installed bundler for gems without any native extensions - Example - Docs
  • Using Docker for gems with OS native C extensions or system libraries like http, Nokogiri - Example - Docs
  • Preinstall OS packages (yum packages) for gems which requires OS native system libraries like pg, mysql, RMagick - PG Example - Docs
  • Using Dockerfile for gems which with other OS Linux image or system libraries and utilities - Example - Docs
  • Using Docker / Dockerfile with environment variable - Docker Example - DockerFile Example - Docs
  • Include / Exclude specific functions from layer configuration - Include Example , Exclude Example - Docs
  • Exclude test and development related gems from layer - Example - Docs
  • Using Bundler.require(:default) to require all gems in handler.rb by respecting Gemfile.lock - Example - Docs

Documentation

Check out the documentation here for,

Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

Please make sure to update the tests as appropriate.

Refer Guidelines for more information.

Author: Navarasu
Source Code: https://github.com/navarasu/serverless-ruby-layer 
License: MIT license

#serverless #ruby #layers #aws 

Serverless Ruby Layer
Lawson  Wehner

Lawson Wehner

1655957460

Strings API Implementation with Communication & Data Container Layers

Wire - communication and data-container layers

Wire - communication and data layers which consist of string keys thus realization of String API when each component of the system - logical or visual - represented as a set of Strings - what it consumes is Data API and what it produces or reacts to is Signals API.

Library aimed to decouple UI from business logic

Schema

It has two layers:

  • Communication Layer (or "bus") consists of "signals" with associated listeners inside specific scope - instances of Wire object. This layer has main API: Wire.add and Wire.send.
  • Data Container Layer - Wire.data, it works as a key-value in-memory map, where value is an instance of WireData object that holds dynamic value and can be subscribed for updates.

WireData also has special implementation for Flutter - WireDataBuilder Widget. This widget makes it possible to reuse business logic in web (with any other UI frameworks like Angular) and in mobile project with Flutter. Take a look at the "example" folder in both repositories (current and wire_flutter) where _shared folder contains reusable code imported in both projects as a dart package (with custom path to package), the folder shared as a separate git branch with git-subrepo

Shared code in Flutter mobile/web and custom HTML dart-web

Also, ported to (Work In Progress):

  • Wire Haxe that can help to compile or better say transpile reusable code in one of the following language: JavaScript, Java, C#, C++, HL, Lua, PHP.

Usage:

Steps from diagram's description above. It's example of counter application (see folder ./example/counter).

Steps: 1, 4, 6 - "box" that processes signals:

class CounterProcessor {
  CounterProcessor() {
    Wire.add(this, CounterSignal.INCREASE, (payload, wireId) {
      Wire.data(CounterDataKeys.COUNT, (value) => (value ?? 0) + 1);
    });
    Wire.add(this, CounterSignal.DECREASE, (payload, wireId) {
      Wire.data(CounterDataKeys.COUNT, (int value) => (value ?? 0) > 0 ? value - 1 : 0);
    });
  }
}

Since there is no Model box in this example, the processor (or controller) updates data by itself the steps 4 and 6 are the part of it.

Steps: 2, 7 - View subscribe to data changes and know how to update itself:

class CounterDisplay extends DomElement {
  CounterDisplay():super(DivElement()) {
    // ... DOM initialization and styling
    final wireData = Wire.data(CounterDataKeys.COUNT);
    wireData.subscribe(update);
    update(wireData.value ?? 0);
  }
  // update or render
  void update(value) { dom.text = value.toString(); }
}

Step: 3 - another View translate UI event to the system signal:

class CounterButton extends DomElement {
  CounterButton(String title, String signal):super(ButtonElement()) {
    // ... DOM initialization and styling
    dom.onClick.listen((_) => Wire.send(signal));
  }
}

Adding wires and WireListeners to the system. In reaction its immediately set new value to data-container layer from function that do decision making Wire.data(CounterDataKeys.COUNT, (oldValue) => newValue).

Steps: 4, 5 - "middleman" who catch all whats happening in the system (in this example it stores counter value to localStorage):

class CounterStorageMiddleware extends WireMiddleware {
  final ls = window.localStorage;

  int getInitialValue() {
    return ls.containsKey(CounterDataKeys.COUNT) ?
      int.parse(ls[CounterDataKeys.COUNT]) : 0;
  }

  @override
  void onData(String key, prevValue, nextValue) {
    print('> CounterMiddleware -> onData: key = ${key} | ${prevValue}-${nextValue}');
    if (key == CounterDataKeys.COUNT) {
      if (nextValue != null) ls[key] = nextValue.toString();
      else { if (ls.containsValue(key)) ls.remove(key); }
    }
  }

  @override void onAdd(Wire wire) { }
  @override void onRemove(String signal, [Object scope, listener]) { }
  @override void onSend(String signal, [data, scope]) { }
}

This "middleman" can be considered as a part of a Model.

Initialization:

void init() {
  final counterStorageMiddleware = CounterStorageMiddleware();
  // Set initial value from local storage
  Wire.data(CounterDataKeys.COUNT, counterStorageMiddleware.getInitialValue());
  // Register middleware after setting initial value to prevent saving initial value
  Wire.middleware(counterStorageMiddleware);
  // Register processor(s) in the system by just creating and instance of it
  processor = CounterProcessor();
  // Create and initialize view parts of the application
  final root = document.querySelector('#root');
  application = ApplicationView(root);
}

That simple!

Preface

Key to a good software product is understanding of how things work together, what do what, software design, separation of concerns and responsibilities, SOLID principles. Here is a good saying from Robert C. Martin:

"Architecture is not about making decisions earlier, but making decisions late. Good architecture is a software structure that allows you to defer critical decisions for as long as possible, defer them to the point where you've got enough information to actually make them, or not make them".

It's always good to protect your business rules from UI changes and make the user interface a plug-in to the business rules, same for domain data make it a plug-in to the business rules and UI.

History

Being in software development over decade now (2020) I have seen many projects built with different tools and technologies, most of them dealt with user interactions and UI layer(s), and I’ve seen, and still see, the same problems everywhere - no strict rules between UI and data, rules are needed to create order, order creates beauty, and beauty survive and thrive. Even if some framework provides these rules and relations between entities they don't have specific tools to force use them, and usually people break them in favor to release feature faster, therefor a software systems could end up in chaos, where business logic mixed with UI and other parts, domain data generate (or resend) from view and coupled with logic of how this data rendered, and other operations that is not related to the view layer (e.g. requests to remote end points). Remember (from Robert C. Martin):

"The only way to go fast, is to go well."

Separation, putting things outside of boundaries, make parts as plugins - that's what I've been thinking about for years, looking at how others work, how things connected, how data propagated through and used in different popular frameworks, in companies custom solutions. And what I realized is that - it all rotated around two concepts:

  1. Data propagation mechanism
  2. Events distribution system

And they both can be represented as an API - Events API and Data API, both could be just a sets of keys without any obligations - set of strings. This idea leads to the concept of layers - two distribution layers one for communication, events or signals, another one for data. That’s how idea of Wire came to life! This way entities expose two parts:

  • what it needs (what data it use or expect to use)
  • what actions it produces (what can be processed)

Component post this information in unique collection of strings - component's Events API and Data API, or it might use general collections shared APIs presented as strings only. Anyway it does not know from where the data come from and who will process actions.

Goal

The aim of this library is to decouple business logic or any logic that makes decisions on data processing, decouple it from UI - this allows to have shared code that can be imported to different projects, with completely different UIs, with any entity.

It's about shared code that can be plug-in or loaded at runtime when it's needed.

General Concepts

A software system consists in leveraging three main concepts:

  1. Data storage and distribution.
  2. Events listening and propagation.
  3. Decision making based on that data (or FSM).

You find these concepts in every program. Basically it's called - Model-View-Controller - meta-pattern or idea of separating program on functional pieces. Understanding MVC is about understanding how programs should work.

Model

Data structure and the ways how to access data define how an application works and how to apply changes. Therefore data definition is the first step in software development. All starts with data. In MVC, the fact that Model is in the first position emphasize it as well. Models in application play a wider role than just value objects definition, it's also a way of how these objects are stored and retrieved, you can think of it as a data API - create, update, delete and etc. Does it make any decisions on how to modify the data? Probably not, maybe only update related data (e.g. in-memory counter of completed todos). And don't forget that there are two types of models - active and passive, one can notify when changes have occurred (active) and another is a plain storage, file or database (passive) - it has to be monitored by a controller or another agent. Next the example of one of TodoModel's methods:

TodoVO create(String text, String note) {
    final todoVO = TodoVO(uuid(), text, note, false);
    final listData = Wire.data(TodoDataParams.LIST);
    final todoList = listData.value as List;
    final count = Wire.data(TodoDataParams.COUNT).value as int;

    todoList.add(todoVO.id);
    Wire.data(todoVO.id, todoVO);
    Wire.data(TodoDataParams.LIST, todoList);
    Wire.data(TodoDataParams.COUNT, count + 1);

    _save();

    print('> TodoModel -> created: ' + todoVO.id + ' - ' + todoVO.text);
    return todoVO;
}

Wire.data('key') plays a role of active model, it holds WireData instances associated with string keys, WireData is a container with data (accessed from .value property) and it can be monitored for updates by subscribing to it - WireData.subscribe((value) => { ... }). To update the value and notify listeners just set the value: Wire.data('key', value). That's simple. It's up to you to decide from where the value (WireData.value) will be updated either from separate entity, a model by calling its data API (together with physical storing in database or sending to a server), or you can do it from controller afterwards when sub-processes will be ended.

View

UI also could have its own state - visual state, and it might not need to be stored in persistent storage at all, only temporarily. Example - accordion’s opened tab, or button hover state, tooltips, input highlight and etc. These states might depend on domain's data and are generated in run-time based on some conditions. Yes, view could have logic inside, but it has to be simple branching conditions and only depends on data passed in, not from multiple data sources, if it is then this is a sign of needed refactoring (for example extracting condition into pre-calculated object property - UserVO.canRoleBeChanged). With Wire view consume data from Data Container Layer - Wire.data(value), then view subscribe to updates and re-render itself when change will happen - WireData.subscribe((value) => { ... }).

class TodoCountView extends DomElement {
  TodoCountView(SpanElement dom):super(dom) {
    var wireData = Wire.data(TodoDataParams.COUNT);
    var update = (value) => dom.innerText = value.toString();
    wireData.subscribe(update);
    update(wireData.value);
  }
}

But not every program has a view, servers might not have UI, and it all depends on the definition of the view. Saying View we mean something that can emit external events about outside world or interaction, and incoming network traffic fit to this definition quite well, and in this case Wire can be a distribution gate for network API calls, just call Wire.send(signal, dto) on network events and every part of internal system can react to it. Wire.send is a Communication Layer - a way to completely separate parts of the application. View sends signals and waits for data to be updated. Other parts of the view can listen for signals as well and update themselves accordingly. Signal is a string type constant and all of them represent Events API of the component or a system.

Controller

Decision making - business logic - the rules, the controller. It's a place where data meet events, their data are mixed with other data, compared and distributed to a model for CRUD operations, then view updates.

We believe and promote the idea that's view is 'just' the UI layer, with the real app being the logic and data kept outside the components tree.

from original article Thoughts on React Hooks, Redux, and Separation of Concerns

Based on this belief we recommend to keep all your business logic, all these data processing and decision making logic outside of a view - in controllers, this is the only right place to do that. Signals listeners placed inside controller. You register a signal by adding it to the Communication Layer with Wire.add(scope, signal, listener). Many signals can be connected to the same listener and vice versa. The listener should follow the specification of WireListener and has two params - data payload it distributes and wire identifier (wid - string constant).

class TodoController {
    TodoModel todoModel;
    TodoController(this.todoModel) {
    
    Wire.add(this, ViewSignals.INPUT, (String data, int wid) {
      var text = data;
      print('> TodoProcessor -> TodoViewOutputSignal.INPUT: ' + text);
      if (text != null && text.isNotEmpty) {
        todoModel.create(text);
        Wire.send(ViewSignals.CLEAR_INPUT);
      }
    });
    
    Wire.add(this, ViewSignals.DELETE, (String data, int wid) {
      var todoId = data;
      print('> TodoProcessor -> TodoViewOutputSignal.DELETE: ' + todoId);
      todoModel.remove(todoId);
    });

    // Or there can be one listener - signal processor
    Wire.add(this, ViewSignals.INPUT,  _signalProcessor);
    Wire.add(this, ViewSignals.EDIT,   _signalProcessor);
    Wire.add(this, ViewSignals.DELETE, _signalProcessor);
    Wire.add(this, ViewSignals.TOGGLE, _signalProcessor);
    // ...
  }

  void _signalProcessor(DTO payload, int wid) {
    var wire = Wire.get(wid: wid).single;
    print('> TodoProcessor -> ${wire.signal}: data = ' + payload.toString());
    // ...
  }
}

In controller you make a decision of how to process input data, do calculation, then data delegated to a model(s), stored or sent to the server, then controller might initiate reaction - send another signal or if data was not updated from model (in Data Container Layer) then controller might update it manually (with Wire.data(key, value)). Application can have multiple controllers each responsible to its particular data processing. You might think of them as reducers from Redux world or commands from PureMVC.

Few words about FLUX

FLUX pattern is a modification of MVC idea, where data flow unidirectional and controllers replaced with so-called "controller-views":

"Views often found at the top of the hierarchy that retrieve data from the stores and pass this data down to their children."

FLUX Diagram

But in general it's all MVC, Wire incorporate these ideas of Flux, but also allows consumers of data additionally react on signals from other parts of the system, basically from anywhere, beside provides a way to manually subscribe to data changes. The basic flow is next:

  1. Consumers request the data and subscribe for its updates - register reactions.
  2. Signals produced somewhere in the system (maybe by the same data consumers) or come from outside (e.g. network requests).
  3. Listeners react to signals and process data coming with them, these listeners are controllers and update data in stores, which then will trigger reactions (also they can send new signals, but its just an options).

Wire in Flutter / WireDataBuilder

Having business logic separated from presentation, events distributed in Communication Layer and data accessible from shared layer (Wire.data) it's now possible to consume the data and send signal from UI easily. In Flutter this means that we can leave visual hierarchy, UI rendering and transitions between screens/pages to the Flutter framework, and consume data in places where it's needed, we can do this with special widget - WireDataBuilder<T>({Key key, String dataKey, Builder builder}) which subscribe with a string dataKey to WireData value and its changes, it rebuilds underlying widget you return from builder function when WireData value updated. However if you need only data in place you still can get it directly with Wire.data('key').value. Here is an example from Todo application: Here is Wire in Flutter

class StatsCounter extends StatelessWidget {
  StatsCounter() : super(key: ArchSampleKeys.statsCounter);
  @override
  Widget build(BuildContext context) {
    return Center(
      child: WireDataBuilder<int>( // <----- Subscribe to update
        dataKey: DataKeys.COUNT, // <------ Data key (string)
        builder: (context, int notCompletedCount) {
          var allTodoCount = Wire.data(DataKeys.LIST).value.length; // <---- Access data without listening for its change
          var numCompleted = allTodoCount - notCompletedCount;
          return Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              ...

WIRE API

Wire (static methods):

Wire .add<T>(Object scope, String signal, WireListener<T> listener, [int replies = 0])
bool .send<T>(String signal, {T payload, Object scope}) // Payload or DTO stands for Data Transfer Object
bool .remove(String signal, {Object scope, WireListener listener})
bool .has({String signal, Wire wire})
void .attach(Wire wire)
bool .detach(Wire wire)
bool .purge()
void .middleware(WireMiddleware value)
List<Wire> .get({String signal, Object scope, WireListener listener, int wid})

WireData .data<T>(String key, [T value])

WireListener:

Definition of listener to a signal in Wire.add(scope, signal, listener) To get signal use Wire.get(wid:wid).single

void Function(T payload, int wid)

WireData:

It is a data container that holds dynamic value. WireData can be subscribed (and unsubscribed). It is associated with string key and retrieved from in-memory map with Wire.data(key). WireData can't be null and Wire.data(key) will always return WireData instance, but its initial value can be null (if first call does not have value, e.g.Wire.data(key, null)), to check this initial null value WireData has special property isSet, which is false until not null value won't be set for the first time. To remove value from Data Container Layer use method remove() - it emits null value before remove subscribers and WireData instance, use isSet property to to distinguish between newly created (false) and removed.

WireData subscribe(WireDataListener<T> listener)
WireData unsubscribe(WireDataListener<T> listener)
void refresh()
void remove()
T get value
bool WireData.lock(WireDataLockToken token)
bool WireData.unlock(WireDataLockToken token)
bool get WireData.isLocked

WireDataListener:

Definition of WireData listener in WireData.subscribe(scope, listener)

void Function(T value);

WireMiddleware:

Class that extends WireMiddleware's methods can be added to Wire.middleware(middleware)

abstract class WireMiddleware {
  void onAdd(Wire wire);
  void onSend(String signal, [payload, scope]);
  void onRemove(String signal, [Object scope, WireListener listener]);
  void onData(String param, dynamic prevValue, dynamic nextValue);
}

UML

Generate UML with dcdg (PlantUML): pub global run dcdg -o ./uml/configuration

Examples

1. Counter (web):

  • Open IDEA
  • Select build target - Dart Web, point to example/counter/index.html
  • Run Debug

2. Todo MVC:

2.1 Dart Web and HTML template:

Todo web with Wire

  • Open IDEA
  • Select build target - Dart Web, point to example/todo/index.html
  • Run Debug

2.2 Todo MVC and Flutter:

Todo Flutter with Wire repo

2.1 Todo Angular

Todo Example with AngularDart using shared code

  • Open IDEA
  • Create symlink (or anchor on Windows) from "_shared/todo" folder in "example" folder and put the link in to "todo_angular/lib/src/_shared" folder.
  • Run DartWeb configuration with index.html

3. API calls variations (console):

  • Open IDEA
  • Select build target - Dart Command Line App, point to example/api/wire_api_example.dart
  • Run Debug

Installing

Use this package as a library

Depend on it

Run this command:

With Dart:

 $ dart pub add wire

With Flutter:

 $ flutter pub add wire

This will add a line like this to your package's pubspec.yaml (and run an implicit dart pub get):

dependencies:
  wire: ^1.4.7

Alternatively, your editor might support dart pub get or flutter pub get. Check the docs for your editor to learn more.

Import it

Now in your Dart code, you can use:

import 'package:wire/wire.dart';

example/README.md

Examples

For every project in example folder you have to run pub get from terminal or from IDE opened pubspec.yaml

(you might need to change the port number if you want to run multiple web apps simultaneously)

1. Counter (web): Simple "Increase/Decrease/Output" example of Wire use

  • Open IDEA or WebStorm
  • Select build target - Dart Web,
  • Set "HTML file" to: example/counter/index.html
  • Run Debug

2. Todo MVC (web): Complex Todo application based on TodoMVC CSS

Todo with Wire

  • Open IDEA or WebStorm
  • Select build target - Dart Web
  • Path to: example/todo/index.html
  • Run Debug

In case an error like:

Building package executable...
Failed to build webdev:webdev:
../../.pub-cache/hosted/pub.dartlang.org/dds-2.1.6/lib/src/cpu_samples_manager.dart:54:21: Error: Type 'CpuSamplesEvent' not found.
void cacheSamples(CpuSamplesEvent samples) {
^^^^^^^^^^^^^^^
../../.pub-cache/hosted/pub.dartlang.org/dds-2.1.6/lib/src/cpu_samples_manager.dart:54:21: Error: 'CpuSamplesEvent' isn't a type.
void cacheSamples(CpuSamplesEvent samples) {

Edited cpu_samples_manager.dart in ~/.pub-cache/hosted/pub.dartlang.org/dds-2.1.6/lib/src/ and remove type CpuSamplesEvent.

3. API calls variations (console): Possible variation of Wire API use

  • Open IDEA
  • Select build target - Dart Command Line App, point to example/api/wire_api_example.dart
  • Run Debug

4. Todo with AngularDart web

(NO SUPPORT FOR NULL-SAFETY - DEPRECATED)

Todo with Wire

  • Open folder from IDEA
  • Create symlink (or anchor on Windows) from "_shared" folder in "example" folder and put the link in to "todo_angular/lib/src/" folder.
  • Run DartWeb configuration with index.html

Setup in IDEA:

To run these examples import them as a module from File -> Project Structure in IDEA and enable Dart SDK for each from Preferences -> Languages & Frameworks -> Dart

Import as module Import as module

Author: WiresWare
Source Code: https://github.com/WiresWare/wire_dart 
License: View license

#flutter #dart #mvc #layers 

Strings API Implementation with Communication & Data Container Layers
Hermann  Frami

Hermann Frami

1655284980

Serverless.js Plugin That Implements AWS Lambda Layers

serverless-layers     

  • It attaches automatically layers to the provider and for each function
    • it will skip functions with no other layers as they will use the layer(s) we added to the provider
  • It creates a new layer's version when dependencies is updated
  • If dependencies is not changed, it does not publish a new layer
  • It reduces drastically lambda size
  • It reduces deployment time.
  • You can share same layers (libraries) among all lambda functions

Common requirements

  • AWS only (sorry)
  • Serverless >= 1.34.0 (layers support)

Install

npm install -D serverless-layers

or

serverless plugin install --name serverless-layers

Add the plugin to your serverless.yml file:

Single layer config

Example:

plugins:
  - serverless-layers
  
custom:
  serverless-layers:
    functions: # optional
      - my_func2
    dependenciesPath: ./package.json

functions:
  my_func1:
    handler: handler.hello
  my_func2:
    handler: handler.hello

Multiple layers config

Example:

plugins:
  - serverless-layers
  
custom:
  serverless-layers:
    # applies for all lambdas 
    - common:
        dependenciesPath: ./my-folder/package.json
    # apply for foo only
    - foo:
        functions:
          - foo
        dependenciesPath: my-folder/package-foo.json
    - staticArn:
        functions:
          - foo
          - bar
        arn: arn:aws:lambda:us-east-1:<your_account>:layer:node-v13-11-0:5

functions:
  foo:
    handler: handler.hello
  bar:
    handler: handler.hello

Screen Shot 2020-04-05 at 2 04 38 pm

OptionTypeDefaultDescription
compileDirstring.serverlessCompilation directory
layersDeploymentBucketstring You can specify a bucket to upload lambda layers. Required if deploymentBucket is not defined.
customInstallationCommandstring It specify a custom command to install deps ex. MY_ENV=1 npm --proxy http://myproxy.com i -P

NodeJS

Requirements

  • Node >= v6.10.3
  • NPM >= 3.10.10
  • A valid package.json file

Options

OptionTypeDefaultDescription
packageManagerstringnpmPossible values: npm, yarn
packagePathstringpackage.json(DEPRECATED): Available for <= 1.5.0, for versions >= 2.x please use compatibleRuntimes
dependenciesPathstringpackage.jsonNote: >= 2.x versions. You can specify custom path for your package.json
compatibleRuntimesarray['nodejs']Possible values: nodejs, nodejs10.x, nodejs12.x

Ruby

Requirements

  • Ruby >= 2.5
  • A valid Gemfile file

Options

OptionTypeDefaultDescription
packageManagerstringbundlePossible values: bundle
dependenciesPathstringGemfileNote: Available for >= 2.x versions. You can specify custom path for your requirements.txt
compatibleRuntimesarray['ruby']Possible values: ruby2.5, ruby2.7

Python

Requirements

  • Python >= 2.7
  • A valid requirements.txt file

Options

OptionTypeDefaultDescription
packageManagerstringpipPossible values: pip
dependenciesPathstringrequirements.txtNote: Available for >= 2.x versions. You can specify custom path for your requirements.txt
compatibleRuntimesarray['python']Possible values: python2.7, python3.6, python3.7 and python3.8

Default Serverless Setup

This plugin will setup follow options automatically if not specified at serverless.yml.

OptionTypeDefault
package.individuallyboolfalse
package.excludearray['node_modules/**']
package.excludeDevDependenciesboolfalse

Mininal Policy permissions for CI/CD IAM users

serverless-layers-policy.json

{
   "Version":"2012-10-17",
   "Statement":[
      {
         "Effect":"Allow",
         "Action":[
            "s3:PutObject",
            "s3:GetObject"
         ],
         "Resource": "arn:aws:s3:::examplebucket"
      },
      {
         "Effect":"Allow",
         "Action":[
            "cloudformation:DescribeStacks"
         ],
         "Resource": "*"
      },
      {
         "Effect":"Allow",
         "Action":[
            "lambda:PublishLayerVersion"
         ],
         "Resource": "*"
      }
   ]
}

Options

Author: Agutoli 
Source Code: https://github.com/agutoli/serverless-layers 
License: MIT license

#serverless #layers #node #ruby #aws #lambda 

Serverless.js Plugin That Implements AWS Lambda Layers
Hermann  Frami

Hermann Frami

1655270040

Serverless Lambda Layer Packager

Serverless Lambda Layer Packager

This Serverless plugin allows you to maintain your normal project structure when developing your Lambda Layer, and you do not have to think about it getting packaged in the correct folder.

Let's say you are making a Python Lambda function with a Python layer, that layer's code will have to be put inside a python/{packagename} folder inside your layer's zip file. This python folder clutters up your workspace and with this plugin, you do not have to think about it. It will put your code inside the correct folder when Serverless packages your layer.

Installation

First, add Serverless Lambda Layer Packager to your project:

npm install serverless-lambda-layer-packager

Then inside your project's serverless.yml file add the following entry to the plugins section: serverless-lambda-layer-packager. If there is no plugin section you will need to add it to the file.

It should look something like this:

plugins:
  - serverless-lambda-layer-packager

You can check wether you have successfully installed the plugin by running the serverless command line:

serverless --help

The console should display ServerlessLambdaLayerPackager as one of the plugins now available in your Serverless project.

Configuration

Inside your serverless.yml file you can specify what folder the plugin has to use for your layer. You can also specify what runtime it has to use, to be able to get the correct files. You can find more about the folders in the AWS Layer configuration documentation

We currently support Python and Node.js runtimes and these are the folder examples:

Python: python/{packagename}
Node.js: nodejs/node_modules/{packagename}

To configure this in the serverless.yml you can add it under custom. For example:

custom:
  serverless-lambda-layer-packager:
    pathPrefix: python/my-layer
    runtime: python3.7

Author: Bramhoven
Source Code: https://github.com/bramhoven/serverless-lambda-layer-packager 
License: 

#serverless #lambda #layers 

Serverless Lambda Layer Packager
Hermann  Frami

Hermann Frami

1654555500

Serverless Newrelic Lambda Layers

serverless-newrelic-lambda-layers

A Serverless plugin to add New Relic observability using AWS Lambda Layers without requiring a code change.

Requirements

  • serverless >= 3.x (v3.x of this plugin has been tested to work with Serverless v2, but future compatibility is not guaranteed.)
  • Node >= 14.x (if using Serverless version 3)

Features

  • Installs and configures the New Relic AWS Integration
  • Supports Node.js, Python and Java runtimes (more runtimes to come)
  • No code change required to enable New Relic
  • Bundles New Relic's agent in a single layer
  • Configures CloudWatch subscription filters automatically

Install

With NPM:

npm install --save-dev serverless-newrelic-lambda-layers

(Note: this plugin's production dependencies are now defined as peer dependencies. NPM v7 and later will install missing peer dependencies automatically, but v6 does not.)

With yarn:

yarn add --dev serverless-newrelic-lambda-layers

Add the plugin to your serverless.yml:

plugins:
  - serverless-newrelic-lambda-layers

If you don't yet have a New Relic account, sign up here.

Grab your New Relic Account ID, your New Relic Personal API Key and plug them into your serverless.yml:

custom:
  newRelic:
    accountId: your-new-relic-account-id-here
    apiKey: your-new-relic-personal-api-key-here

Deploy:

sls deploy

And you're all set.

Usage

This plugin wraps your handlers without requiring a code change. If you're currently using a New Relic agent, you can remove the wrapping code you currently have and this plugin will do it for you automatically.

Config

The following config options are available via the newRelic section of the custom section of your serverless.yml:

accountId (required)

Your New Relic Account ID.

custom:
  newRelic:
    accountId: your-account-id-here

apiKey (required)

Your New Relic Personal API Key.

custom:
  newRelic:
    apiKey: your-api-key-here

If your function's source is committed to version control, you can avoid committing your license key by including it in your serverless.yml as a variable. See the Serverless docs on template variables for more information.

nrRegion (required for EU; optional for US)

If your New Relic account is based in the EU, make sure to specify your nrRegion in the custom block:

custom:
  newRelic:
    nrRegion: 'eu'

linkedAccount (optional)

A label for the New Relic Linked Account. This is how this integration will appear in New Relic. If not set, it will default to "New Relic Lambda Integration - ".

custom:
  newRelic:
    linkedAccount: your-linked-account-name

trustedAccountKey (optional)

Only required if your New Relic account is a sub-account. This needs to be the account ID for the root/parent account.

custom:
  newRelic:
    trustedAccountKey: your-parent-account-id

debug (optional)

Whether or not to enable debug mode. Must be a boolean value. This sets the log level to debug.

custom:
  newRelic:
    debug: true

enableExtension (optional)

Allows your function to deliver its telemetry to New Relic via AWS Lambda Extension. Defaults to true, so it can be omitted. To avoid delivering your telemetry via the extension, set to false.

custom:
  newRelic:
    enableExtension: true

enableFunctionLogs (optional)

Allows your function to deliver all of your function logs to New Relic via AWS Lambda Extension. This would eliminate the need for a CloudWatch log subscription + the NR log ingestion Lambda function. This method of log ingestion is lower-cost, and offers faster time to glass.

custom:
  newRelic:
    enableFunctionLogs: true

enableExtensionLogs (optional)

The New Relic Lambda Extension writes diagnostic logs by default. If you'd prefer to mute them, set this to false. (Defaults to true.)

custom:
  newRelic:
    enableExtensionLogs: false

logEnabled (optional)

Enables logging when using CloudWatch-based telemetry transport with the newrelic-log-ingestion Lambda function. Defaults to false

enableIntegration (optional)

Allows the creation of New Relic aws cloud integration when absent. Defaults to false. If an integration already exists for your AWS account,you can omit this.

custom:
  newRelic:
    enableIntegration: true

logLevel (optional)

Sets a log level on all functions. Possible values: 'fatal', 'error', 'warn', 'info', 'debug', 'trace' or 'silent'. Defaults to 'error'

You can still override log level on a per function basis by configuring environment variable NEW_RELIC_LOG_LEVEL.

custom:
  newRelic:
    logLevel: debug

Logging configuration is considered in the following order:

  1. function NEW_RELIC_LOG_LEVEL environment
  2. provider NEW_RELIC_LOG_LEVEL environment
  3. custom newRelic logLevel property
  4. custom newRelic debug flag

customRolePolicy (optional)

Specify an alternative IAM role policy ARN for this integration here if you do not want to use the default role policy.

custom:
  newRelic:
    customRolePolicy: your-custom-role-policy-arn

stages (optional)

An array of stages that the plugin will be included for. If this key is not specified then all stages will be included.

custom:
  newRelic:
    stages:
       - prod

include (optional)

An array of functions to include for automatic wrapping. (You can set include or exclude options, but not both.)

custom:
  newRelic:
    include:
      - include-only-func
      - another-included-func

exclude (optional)

An array of functions to exclude from automatic wrapping. (You can set include or exclude options, but not both.)

custom:
  newRelic:
    exclude:
      - excluded-func-1
      - another-excluded-func

layerArn (optional)

Pin to a specific layer version. The latest layer ARN is automatically fetched from the New Relic Layers API

custom:
  newRelic:
    layerArn: arn:aws:lambda:us-east-1:451483290750:layer:NewRelicPython37:2

cloudWatchFilter (optional)

Provide a list of quoted filter terms for the CloudWatch log subscription to the newrelic-log-ingestion Lambda. Combines all terms into an OR filter. Defaults to "NR_LAMBDA_MONITORING" if not set. Use "*" to capture all logs

custom:
  newRelic:
    cloudWatchFilter:
      - "NR_LAMBDA_MONITORING"
      - "trace this"
      - "ERROR"

If you want to collect all logs:

custom:
  newRelic:
    cloudWatchFilter: "*"

Be sure to set the LOGGING_ENABLED environment variable to true in your log ingestion function. See the aws-log-ingestion documentation for details.

prepend (optional)

Whether or not to prepend the New Relic layer. Defaults to false which appends the layer.

custom:
  newRelic:
    prepend: true

logIngestionFunctionName (optional)

Only required if your New Relic log ingestion function name is different from newrelic-log-ingestion.

custom:
  newRelic:
    logIngestionFunctionName: log-ingestion-service

disableAutoSubscription (optional)

Only required if you want to disable auto subscription.

custom:
  newRelic:
    disableAutoSubscription: true

disableLicenseKeySecret (optional)

Only required if you want to disable creating license key in AWS Secrets Manager. Setting this as true would create NEW_RELIC_LICENSE_KEY environment variable for the New Relic Lambda Extension to access.

custom:
  newRelic:
    disableLicenseKeySecret: true

javaNewRelicHandler (optional)

Java runtimes only. Only required if you are implementing the RequestStreamHandler interface. Defaults to RequestHandler interface.

Accepted inputs:

  • handleRequest
  • handleStreamsRequest
custom:
  newRelic:
    javaNewRelicHandler: handleStreamsRequest

proxy (optional)

This plugin makes various HTTP requests to public APIs in order to retrieve data about the New Relic and cloud provider accounts. If you are behind a proxy when this plugin runs, the HTTP agent needs the proxy information to connect to those APIs. Use the given URL as a proxy for HTTP requests.

custom:
  newRelic:
    proxy: http://yourproxy.com:8080

Supported Runtimes

This plugin currently supports the following AWS runtimes:

  • nodejs12.x
  • nodejs14.x
  • nodejs16.x
  • python3.6
  • python3.7
  • python3.8
  • python3.9
  • java11
  • java8.al2

Contributing

Testing

  1. Make changes to examples/nodejs/serverless.yml based on what you are planning to test
  2. Generate a test case by executing script generate:test:case
# Example
npm run generate:test:case
  1. Rename generated file tests/fixtures/example.service.input.json to test case e.g. tests/fixtures/log-level.service.input.json
  2. Create expected output file tests/fixtures/example.service.output.json for test case e.g. tests/fixtures/log-level.service.output.json
  3. Run tests
# Example
npm run test

Author: Newrelic
Source Code: https://github.com/newrelic/serverless-newrelic-lambda-layers 
License: Apache-2.0 license

#serverless #layers #lambda 

Serverless Newrelic Lambda Layers
Joseph  Murray

Joseph Murray

1622630880

Looking for the Best Java Data Computation Layer Tool

Looking for the Best Java Data Computation Layer Tool

In most cases, structured data is computed within the database in SQL. In a few other cases where the database is either absent or unavailable, Java programmers need to perform computations with Java. Hardcoding, however, involves a heavy workload. A more convenient alternative is the Java data computation layer tool (including library functions). The tool computes data and returns the result set. Here we examine the structured data computation abilities of several Java data computation layer tools.

#java #tools #comparison #layers #java computing

Looking for the Best Java Data Computation Layer Tool
Lindsey  Koepp

Lindsey Koepp

1594695600

UIBezierPath Lesson: How to draw Cuphead on layers

I have a lot of custom shape layers and bezier paths on my last projects. I want to share my experience in custom shapes drawing. The knowledge about Core Animation has some interesting problems. As for me, the main problem here is rare in custom shapes using. So only sometimes you need to draw something custom, and you don’t have, such experience in that, because it isn’t a core knowledge of iOS developer. Don’t get me wrong. I am talking developers with 1–2 years of experience and I think that I know why. A developer like I said above has a list of must-have skills and Core Animation not a part of them. That’s why some developers have knowledge gaps in custom shapes drawing.

BezierPath has a lot of ways to draw elements of shape. We will talk only about used here. In this post, we will use the most used ways to draw custom shapes. I think it can be a good start for developers who have problems and misunderstandings about shapes drawing. We will draw a cuphead like in the screen below.

Image for post

Theoretical Part

  1. Parts of BezierPath: Line, QuadCurve, Curve, UIBezier ready to use predefined shapes (rectangles, ovals, circles, the arc of circles, rounded rectangles.
  2. How to create shapes from bezier paths.

The coordinate system in CAlayers

The coordinate system inside the layer is a little bit different from the Cartesian coordinate system. In the layer coordinate system, you don’t have a negative value, and all shapes will draw from the left-top corner. You can see an empty coordinate system below. It will have a gray background for better understanding.

Image for post

#core-animation #ios #layers #drawing

UIBezierPath Lesson: How to draw Cuphead on layers